﻿// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System;
using System.Buffers.Binary;

namespace Azure.Storage
{
    /// <summary>
    /// Port of https://github.com/Azure/azure-storage-net/blob/master/Lib/Common/Core/Util/Crc64.cs
    /// and the code used by Azure Storage to compute a CRC-64 with custom polynomial.
    /// </summary>
    internal static class StorageCrc64Calculator
    {
        private static ulong poly = 0x9A6C9329AC4BC9B5UL;

        private static UInt64[] m_u1 =
        {
            0x0000000000000000UL, 0x7f6ef0c830358979UL, 0xfedde190606b12f2UL, 0x81b31158505e9b8bUL,
            0xc962e5739841b68fUL, 0xb60c15bba8743ff6UL, 0x37bf04e3f82aa47dUL, 0x48d1f42bc81f2d04UL,
            0xa61cecb46814fe75UL, 0xd9721c7c5821770cUL, 0x58c10d24087fec87UL, 0x27affdec384a65feUL,
            0x6f7e09c7f05548faUL, 0x1010f90fc060c183UL, 0x91a3e857903e5a08UL, 0xeecd189fa00bd371UL,
            0x78e0ff3b88be6f81UL, 0x078e0ff3b88be6f8UL, 0x863d1eabe8d57d73UL, 0xf953ee63d8e0f40aUL,
            0xb1821a4810ffd90eUL, 0xceecea8020ca5077UL, 0x4f5ffbd87094cbfcUL, 0x30310b1040a14285UL,
            0xdefc138fe0aa91f4UL, 0xa192e347d09f188dUL, 0x2021f21f80c18306UL, 0x5f4f02d7b0f40a7fUL,
            0x179ef6fc78eb277bUL, 0x68f0063448deae02UL, 0xe943176c18803589UL, 0x962de7a428b5bcf0UL,
            0xf1c1fe77117cdf02UL, 0x8eaf0ebf2149567bUL, 0x0f1c1fe77117cdf0UL, 0x7072ef2f41224489UL,
            0x38a31b04893d698dUL, 0x47cdebccb908e0f4UL, 0xc67efa94e9567b7fUL, 0xb9100a5cd963f206UL,
            0x57dd12c379682177UL, 0x28b3e20b495da80eUL, 0xa900f35319033385UL, 0xd66e039b2936bafcUL,
            0x9ebff7b0e12997f8UL, 0xe1d10778d11c1e81UL, 0x606216208142850aUL, 0x1f0ce6e8b1770c73UL,
            0x8921014c99c2b083UL, 0xf64ff184a9f739faUL, 0x77fce0dcf9a9a271UL, 0x08921014c99c2b08UL,
            0x4043e43f0183060cUL, 0x3f2d14f731b68f75UL, 0xbe9e05af61e814feUL, 0xc1f0f56751dd9d87UL,
            0x2f3dedf8f1d64ef6UL, 0x50531d30c1e3c78fUL, 0xd1e00c6891bd5c04UL, 0xae8efca0a188d57dUL,
            0xe65f088b6997f879UL, 0x9931f84359a27100UL, 0x1882e91b09fcea8bUL, 0x67ec19d339c963f2UL,
            0xd75adabd7a6e2d6fUL, 0xa8342a754a5ba416UL, 0x29873b2d1a053f9dUL, 0x56e9cbe52a30b6e4UL,
            0x1e383fcee22f9be0UL, 0x6156cf06d21a1299UL, 0xe0e5de5e82448912UL, 0x9f8b2e96b271006bUL,
            0x71463609127ad31aUL, 0x0e28c6c1224f5a63UL, 0x8f9bd7997211c1e8UL, 0xf0f5275142244891UL,
            0xb824d37a8a3b6595UL, 0xc74a23b2ba0eececUL, 0x46f932eaea507767UL, 0x3997c222da65fe1eUL,
            0xafba2586f2d042eeUL, 0xd0d4d54ec2e5cb97UL, 0x5167c41692bb501cUL, 0x2e0934dea28ed965UL,
            0x66d8c0f56a91f461UL, 0x19b6303d5aa47d18UL, 0x980521650afae693UL, 0xe76bd1ad3acf6feaUL,
            0x09a6c9329ac4bc9bUL, 0x76c839faaaf135e2UL, 0xf77b28a2faafae69UL, 0x8815d86aca9a2710UL,
            0xc0c42c4102850a14UL, 0xbfaadc8932b0836dUL, 0x3e19cdd162ee18e6UL, 0x41773d1952db919fUL,
            0x269b24ca6b12f26dUL, 0x59f5d4025b277b14UL, 0xd846c55a0b79e09fUL, 0xa72835923b4c69e6UL,
            0xeff9c1b9f35344e2UL, 0x90973171c366cd9bUL, 0x1124202993385610UL, 0x6e4ad0e1a30ddf69UL,
            0x8087c87e03060c18UL, 0xffe938b633338561UL, 0x7e5a29ee636d1eeaUL, 0x0134d92653589793UL,
            0x49e52d0d9b47ba97UL, 0x368bddc5ab7233eeUL, 0xb738cc9dfb2ca865UL, 0xc8563c55cb19211cUL,
            0x5e7bdbf1e3ac9decUL, 0x21152b39d3991495UL, 0xa0a63a6183c78f1eUL, 0xdfc8caa9b3f20667UL,
            0x97193e827bed2b63UL, 0xe877ce4a4bd8a21aUL, 0x69c4df121b863991UL, 0x16aa2fda2bb3b0e8UL,
            0xf86737458bb86399UL, 0x8709c78dbb8deae0UL, 0x06bad6d5ebd3716bUL, 0x79d4261ddbe6f812UL,
            0x3105d23613f9d516UL, 0x4e6b22fe23cc5c6fUL, 0xcfd833a67392c7e4UL, 0xb0b6c36e43a74e9dUL,
            0x9a6c9329ac4bc9b5UL, 0xe50263e19c7e40ccUL, 0x64b172b9cc20db47UL, 0x1bdf8271fc15523eUL,
            0x530e765a340a7f3aUL, 0x2c608692043ff643UL, 0xadd397ca54616dc8UL, 0xd2bd67026454e4b1UL,
            0x3c707f9dc45f37c0UL, 0x431e8f55f46abeb9UL, 0xc2ad9e0da4342532UL, 0xbdc36ec59401ac4bUL,
            0xf5129aee5c1e814fUL, 0x8a7c6a266c2b0836UL, 0x0bcf7b7e3c7593bdUL, 0x74a18bb60c401ac4UL,
            0xe28c6c1224f5a634UL, 0x9de29cda14c02f4dUL, 0x1c518d82449eb4c6UL, 0x633f7d4a74ab3dbfUL,
            0x2bee8961bcb410bbUL, 0x548079a98c8199c2UL, 0xd53368f1dcdf0249UL, 0xaa5d9839ecea8b30UL,
            0x449080a64ce15841UL, 0x3bfe706e7cd4d138UL, 0xba4d61362c8a4ab3UL, 0xc52391fe1cbfc3caUL,
            0x8df265d5d4a0eeceUL, 0xf29c951de49567b7UL, 0x732f8445b4cbfc3cUL, 0x0c41748d84fe7545UL,
            0x6bad6d5ebd3716b7UL, 0x14c39d968d029fceUL, 0x95708ccedd5c0445UL, 0xea1e7c06ed698d3cUL,
            0xa2cf882d2576a038UL, 0xdda178e515432941UL, 0x5c1269bd451db2caUL, 0x237c997575283bb3UL,
            0xcdb181ead523e8c2UL, 0xb2df7122e51661bbUL, 0x336c607ab548fa30UL, 0x4c0290b2857d7349UL,
            0x04d364994d625e4dUL, 0x7bbd94517d57d734UL, 0xfa0e85092d094cbfUL, 0x856075c11d3cc5c6UL,
            0x134d926535897936UL, 0x6c2362ad05bcf04fUL, 0xed9073f555e26bc4UL, 0x92fe833d65d7e2bdUL,
            0xda2f7716adc8cfb9UL, 0xa54187de9dfd46c0UL, 0x24f29686cda3dd4bUL, 0x5b9c664efd965432UL,
            0xb5517ed15d9d8743UL, 0xca3f8e196da80e3aUL, 0x4b8c9f413df695b1UL, 0x34e26f890dc31cc8UL,
            0x7c339ba2c5dc31ccUL, 0x035d6b6af5e9b8b5UL, 0x82ee7a32a5b7233eUL, 0xfd808afa9582aa47UL,
            0x4d364994d625e4daUL, 0x3258b95ce6106da3UL, 0xb3eba804b64ef628UL, 0xcc8558cc867b7f51UL,
            0x8454ace74e645255UL, 0xfb3a5c2f7e51db2cUL, 0x7a894d772e0f40a7UL, 0x05e7bdbf1e3ac9deUL,
            0xeb2aa520be311aafUL, 0x944455e88e0493d6UL, 0x15f744b0de5a085dUL, 0x6a99b478ee6f8124UL,
            0x224840532670ac20UL, 0x5d26b09b16452559UL, 0xdc95a1c3461bbed2UL, 0xa3fb510b762e37abUL,
            0x35d6b6af5e9b8b5bUL, 0x4ab846676eae0222UL, 0xcb0b573f3ef099a9UL, 0xb465a7f70ec510d0UL,
            0xfcb453dcc6da3dd4UL, 0x83daa314f6efb4adUL, 0x0269b24ca6b12f26UL, 0x7d0742849684a65fUL,
            0x93ca5a1b368f752eUL, 0xeca4aad306bafc57UL, 0x6d17bb8b56e467dcUL, 0x12794b4366d1eea5UL,
            0x5aa8bf68aecec3a1UL, 0x25c64fa09efb4ad8UL, 0xa4755ef8cea5d153UL, 0xdb1bae30fe90582aUL,
            0xbcf7b7e3c7593bd8UL, 0xc399472bf76cb2a1UL, 0x422a5673a732292aUL, 0x3d44a6bb9707a053UL,
            0x759552905f188d57UL, 0x0afba2586f2d042eUL, 0x8b48b3003f739fa5UL, 0xf42643c80f4616dcUL,
            0x1aeb5b57af4dc5adUL, 0x6585ab9f9f784cd4UL, 0xe436bac7cf26d75fUL, 0x9b584a0fff135e26UL,
            0xd389be24370c7322UL, 0xace74eec0739fa5bUL, 0x2d545fb4576761d0UL, 0x523aaf7c6752e8a9UL,
            0xc41748d84fe75459UL, 0xbb79b8107fd2dd20UL, 0x3acaa9482f8c46abUL, 0x45a459801fb9cfd2UL,
            0x0d75adabd7a6e2d6UL, 0x721b5d63e7936bafUL, 0xf3a84c3bb7cdf024UL, 0x8cc6bcf387f8795dUL,
            0x620ba46c27f3aa2cUL, 0x1d6554a417c62355UL, 0x9cd645fc4798b8deUL, 0xe3b8b53477ad31a7UL,
            0xab69411fbfb21ca3UL, 0xd407b1d78f8795daUL, 0x55b4a08fdfd90e51UL, 0x2ada5047efec8728UL,
        };

        private static UInt64[] m_u32 =
        {
            0x0000000000000000UL, 0xb8c533c1177eb231UL, 0x455341d1766af709UL, 0xfd96721061144538UL,
            0x8aa683a2ecd5ee12UL, 0x3263b063fbab5c23UL, 0xcff5c2739abf191bUL, 0x7730f1b28dc1ab2aUL,
            0x21942116813c4f4fUL, 0x995112d79642fd7eUL, 0x64c760c7f756b846UL, 0xdc025306e0280a77UL,
            0xab32a2b46de9a15dUL, 0x13f791757a97136cUL, 0xee61e3651b835654UL, 0x56a4d0a40cfde465UL,
            0x4328422d02789e9eUL, 0xfbed71ec15062cafUL, 0x067b03fc74126997UL, 0xbebe303d636cdba6UL,
            0xc98ec18feead708cUL, 0x714bf24ef9d3c2bdUL, 0x8cdd805e98c78785UL, 0x3418b39f8fb935b4UL,
            0x62bc633b8344d1d1UL, 0xda7950fa943a63e0UL, 0x27ef22eaf52e26d8UL, 0x9f2a112be25094e9UL,
            0xe81ae0996f913fc3UL, 0x50dfd35878ef8df2UL, 0xad49a14819fbc8caUL, 0x158c92890e857afbUL,
            0x8650845a04f13d3cUL, 0x3e95b79b138f8f0dUL, 0xc303c58b729bca35UL, 0x7bc6f64a65e57804UL,
            0x0cf607f8e824d32eUL, 0xb4333439ff5a611fUL, 0x49a546299e4e2427UL, 0xf16075e889309616UL,
            0xa7c4a54c85cd7273UL, 0x1f01968d92b3c042UL, 0xe297e49df3a7857aUL, 0x5a52d75ce4d9374bUL,
            0x2d6226ee69189c61UL, 0x95a7152f7e662e50UL, 0x6831673f1f726b68UL, 0xd0f454fe080cd959UL,
            0xc578c6770689a3a2UL, 0x7dbdf5b611f71193UL, 0x802b87a670e354abUL, 0x38eeb467679de69aUL,
            0x4fde45d5ea5c4db0UL, 0xf71b7614fd22ff81UL, 0x0a8d04049c36bab9UL, 0xb24837c58b480888UL,
            0xe4ece76187b5ecedUL, 0x5c29d4a090cb5edcUL, 0xa1bfa6b0f1df1be4UL, 0x197a9571e6a1a9d5UL,
            0x6e4a64c36b6002ffUL, 0xd68f57027c1eb0ceUL, 0x2b1925121d0af5f6UL, 0x93dc16d30a7447c7UL,
            0x38782ee75175e913UL, 0x80bd1d26460b5b22UL, 0x7d2b6f36271f1e1aUL, 0xc5ee5cf73061ac2bUL,
            0xb2dead45bda00701UL, 0x0a1b9e84aadeb530UL, 0xf78dec94cbcaf008UL, 0x4f48df55dcb44239UL,
            0x19ec0ff1d049a65cUL, 0xa1293c30c737146dUL, 0x5cbf4e20a6235155UL, 0xe47a7de1b15de364UL,
            0x934a8c533c9c484eUL, 0x2b8fbf922be2fa7fUL, 0xd619cd824af6bf47UL, 0x6edcfe435d880d76UL,
            0x7b506cca530d778dUL, 0xc3955f0b4473c5bcUL, 0x3e032d1b25678084UL, 0x86c61eda321932b5UL,
            0xf1f6ef68bfd8999fUL, 0x4933dca9a8a62baeUL, 0xb4a5aeb9c9b26e96UL, 0x0c609d78deccdca7UL,
            0x5ac44ddcd23138c2UL, 0xe2017e1dc54f8af3UL, 0x1f970c0da45bcfcbUL, 0xa7523fccb3257dfaUL,
            0xd062ce7e3ee4d6d0UL, 0x68a7fdbf299a64e1UL, 0x95318faf488e21d9UL, 0x2df4bc6e5ff093e8UL,
            0xbe28aabd5584d42fUL, 0x06ed997c42fa661eUL, 0xfb7beb6c23ee2326UL, 0x43bed8ad34909117UL,
            0x348e291fb9513a3dUL, 0x8c4b1adeae2f880cUL, 0x71dd68cecf3bcd34UL, 0xc9185b0fd8457f05UL,
            0x9fbc8babd4b89b60UL, 0x2779b86ac3c62951UL, 0xdaefca7aa2d26c69UL, 0x622af9bbb5acde58UL,
            0x151a0809386d7572UL, 0xaddf3bc82f13c743UL, 0x504949d84e07827bUL, 0xe88c7a195979304aUL,
            0xfd00e89057fc4ab1UL, 0x45c5db514082f880UL, 0xb853a9412196bdb8UL, 0x00969a8036e80f89UL,
            0x77a66b32bb29a4a3UL, 0xcf6358f3ac571692UL, 0x32f52ae3cd4353aaUL, 0x8a301922da3de19bUL,
            0xdc94c986d6c005feUL, 0x6451fa47c1beb7cfUL, 0x99c78857a0aaf2f7UL, 0x2102bb96b7d440c6UL,
            0x56324a243a15ebecUL, 0xeef779e52d6b59ddUL, 0x13610bf54c7f1ce5UL, 0xaba438345b01aed4UL,
            0x70f05dcea2ebd226UL, 0xc8356e0fb5956017UL, 0x35a31c1fd481252fUL, 0x8d662fdec3ff971eUL,
            0xfa56de6c4e3e3c34UL, 0x4293edad59408e05UL, 0xbf059fbd3854cb3dUL, 0x07c0ac7c2f2a790cUL,
            0x51647cd823d79d69UL, 0xe9a14f1934a92f58UL, 0x14373d0955bd6a60UL, 0xacf20ec842c3d851UL,
            0xdbc2ff7acf02737bUL, 0x6307ccbbd87cc14aUL, 0x9e91beabb9688472UL, 0x26548d6aae163643UL,
            0x33d81fe3a0934cb8UL, 0x8b1d2c22b7edfe89UL, 0x768b5e32d6f9bbb1UL, 0xce4e6df3c1870980UL,
            0xb97e9c414c46a2aaUL, 0x01bbaf805b38109bUL, 0xfc2ddd903a2c55a3UL, 0x44e8ee512d52e792UL,
            0x124c3ef521af03f7UL, 0xaa890d3436d1b1c6UL, 0x571f7f2457c5f4feUL, 0xefda4ce540bb46cfUL,
            0x98eabd57cd7aede5UL, 0x202f8e96da045fd4UL, 0xddb9fc86bb101aecUL, 0x657ccf47ac6ea8ddUL,
            0xf6a0d994a61aef1aUL, 0x4e65ea55b1645d2bUL, 0xb3f39845d0701813UL, 0x0b36ab84c70eaa22UL,
            0x7c065a364acf0108UL, 0xc4c369f75db1b339UL, 0x39551be73ca5f601UL, 0x819028262bdb4430UL,
            0xd734f8822726a055UL, 0x6ff1cb4330581264UL, 0x9267b953514c575cUL, 0x2aa28a924632e56dUL,
            0x5d927b20cbf34e47UL, 0xe55748e1dc8dfc76UL, 0x18c13af1bd99b94eUL, 0xa0040930aae70b7fUL,
            0xb5889bb9a4627184UL, 0x0d4da878b31cc3b5UL, 0xf0dbda68d208868dUL, 0x481ee9a9c57634bcUL,
            0x3f2e181b48b79f96UL, 0x87eb2bda5fc92da7UL, 0x7a7d59ca3edd689fUL, 0xc2b86a0b29a3daaeUL,
            0x941cbaaf255e3ecbUL, 0x2cd9896e32208cfaUL, 0xd14ffb7e5334c9c2UL, 0x698ac8bf444a7bf3UL,
            0x1eba390dc98bd0d9UL, 0xa67f0accdef562e8UL, 0x5be978dcbfe127d0UL, 0xe32c4b1da89f95e1UL,
            0x48887329f39e3b35UL, 0xf04d40e8e4e08904UL, 0x0ddb32f885f4cc3cUL, 0xb51e0139928a7e0dUL,
            0xc22ef08b1f4bd527UL, 0x7aebc34a08356716UL, 0x877db15a6921222eUL, 0x3fb8829b7e5f901fUL,
            0x691c523f72a2747aUL, 0xd1d961fe65dcc64bUL, 0x2c4f13ee04c88373UL, 0x948a202f13b63142UL,
            0xe3bad19d9e779a68UL, 0x5b7fe25c89092859UL, 0xa6e9904ce81d6d61UL, 0x1e2ca38dff63df50UL,
            0x0ba03104f1e6a5abUL, 0xb36502c5e698179aUL, 0x4ef370d5878c52a2UL, 0xf636431490f2e093UL,
            0x8106b2a61d334bb9UL, 0x39c381670a4df988UL, 0xc455f3776b59bcb0UL, 0x7c90c0b67c270e81UL,
            0x2a34101270daeae4UL, 0x92f123d367a458d5UL, 0x6f6751c306b01dedUL, 0xd7a2620211ceafdcUL,
            0xa09293b09c0f04f6UL, 0x1857a0718b71b6c7UL, 0xe5c1d261ea65f3ffUL, 0x5d04e1a0fd1b41ceUL,
            0xced8f773f76f0609UL, 0x761dc4b2e011b438UL, 0x8b8bb6a28105f100UL, 0x334e8563967b4331UL,
            0x447e74d11bbae81bUL, 0xfcbb47100cc45a2aUL, 0x012d35006dd01f12UL, 0xb9e806c17aaead23UL,
            0xef4cd66576534946UL, 0x5789e5a4612dfb77UL, 0xaa1f97b40039be4fUL, 0x12daa47517470c7eUL,
            0x65ea55c79a86a754UL, 0xdd2f66068df81565UL, 0x20b91416ecec505dUL, 0x987c27d7fb92e26cUL,
            0x8df0b55ef5179897UL, 0x3535869fe2692aa6UL, 0xc8a3f48f837d6f9eUL, 0x7066c74e9403ddafUL,
            0x075636fc19c27685UL, 0xbf93053d0ebcc4b4UL, 0x4205772d6fa8818cUL, 0xfac044ec78d633bdUL,
            0xac649448742bd7d8UL, 0x14a1a789635565e9UL, 0xe937d599024120d1UL, 0x51f2e658153f92e0UL,
            0x26c217ea98fe39caUL, 0x9e07242b8f808bfbUL, 0x6391563bee94cec3UL, 0xdb5465faf9ea7cf2UL,

            0x0000000000000000UL, 0xf6f734b768e04748UL, 0xd9374f3d89571dfbUL, 0x2fc07b8ae1b75ab3UL,
            0x86b7b8284a39a89dUL, 0x70408c9f22d9efd5UL, 0x5f80f715c36eb566UL, 0xa977c3a2ab8ef22eUL,
            0x39b65603cce4c251UL, 0xcf4162b4a4048519UL, 0xe081193e45b3dfaaUL, 0x16762d892d5398e2UL,
            0xbf01ee2b86dd6accUL, 0x49f6da9cee3d2d84UL, 0x6636a1160f8a7737UL, 0x90c195a1676a307fUL,
            0x736cac0799c984a2UL, 0x859b98b0f129c3eaUL, 0xaa5be33a109e9959UL, 0x5cacd78d787ede11UL,
            0xf5db142fd3f02c3fUL, 0x032c2098bb106b77UL, 0x2cec5b125aa731c4UL, 0xda1b6fa53247768cUL,
            0x4adafa04552d46f3UL, 0xbc2dceb33dcd01bbUL, 0x93edb539dc7a5b08UL, 0x651a818eb49a1c40UL,
            0xcc6d422c1f14ee6eUL, 0x3a9a769b77f4a926UL, 0x155a0d119643f395UL, 0xe3ad39a6fea3b4ddUL,
            0xe6d9580f33930944UL, 0x102e6cb85b734e0cUL, 0x3fee1732bac414bfUL, 0xc9192385d22453f7UL,
            0x606ee02779aaa1d9UL, 0x9699d490114ae691UL, 0xb959af1af0fdbc22UL, 0x4fae9bad981dfb6aUL,
            0xdf6f0e0cff77cb15UL, 0x29983abb97978c5dUL, 0x065841317620d6eeUL, 0xf0af75861ec091a6UL,
            0x59d8b624b54e6388UL, 0xaf2f8293ddae24c0UL, 0x80eff9193c197e73UL, 0x7618cdae54f9393bUL,
            0x95b5f408aa5a8de6UL, 0x6342c0bfc2bacaaeUL, 0x4c82bb35230d901dUL, 0xba758f824bedd755UL,
            0x13024c20e063257bUL, 0xe5f5789788836233UL, 0xca35031d69343880UL, 0x3cc237aa01d47fc8UL,
            0xac03a20b66be4fb7UL, 0x5af496bc0e5e08ffUL, 0x7534ed36efe9524cUL, 0x83c3d98187091504UL,
            0x2ab41a232c87e72aUL, 0xdc432e944467a062UL, 0xf383551ea5d0fad1UL, 0x057461a9cd30bd99UL,
            0xf96b964d3fb181e3UL, 0x0f9ca2fa5751c6abUL, 0x205cd970b6e69c18UL, 0xd6abedc7de06db50UL,
            0x7fdc2e657588297eUL, 0x892b1ad21d686e36UL, 0xa6eb6158fcdf3485UL, 0x501c55ef943f73cdUL,
            0xc0ddc04ef35543b2UL, 0x362af4f99bb504faUL, 0x19ea8f737a025e49UL, 0xef1dbbc412e21901UL,
            0x466a7866b96ceb2fUL, 0xb09d4cd1d18cac67UL, 0x9f5d375b303bf6d4UL, 0x69aa03ec58dbb19cUL,
            0x8a073a4aa6780541UL, 0x7cf00efdce984209UL, 0x533075772f2f18baUL, 0xa5c741c047cf5ff2UL,
            0x0cb08262ec41addcUL, 0xfa47b6d584a1ea94UL, 0xd587cd5f6516b027UL, 0x2370f9e80df6f76fUL,
            0xb3b16c496a9cc710UL, 0x454658fe027c8058UL, 0x6a862374e3cbdaebUL, 0x9c7117c38b2b9da3UL,
            0x3506d46120a56f8dUL, 0xc3f1e0d6484528c5UL, 0xec319b5ca9f27276UL, 0x1ac6afebc112353eUL,
            0x1fb2ce420c2288a7UL, 0xe945faf564c2cfefUL, 0xc685817f8575955cUL, 0x3072b5c8ed95d214UL,
            0x9905766a461b203aUL, 0x6ff242dd2efb6772UL, 0x40323957cf4c3dc1UL, 0xb6c50de0a7ac7a89UL,
            0x26049841c0c64af6UL, 0xd0f3acf6a8260dbeUL, 0xff33d77c4991570dUL, 0x09c4e3cb21711045UL,
            0xa0b320698affe26bUL, 0x564414dee21fa523UL, 0x79846f5403a8ff90UL, 0x8f735be36b48b8d8UL,
            0x6cde624595eb0c05UL, 0x9a2956f2fd0b4b4dUL, 0xb5e92d781cbc11feUL, 0x431e19cf745c56b6UL,
            0xea69da6ddfd2a498UL, 0x1c9eeedab732e3d0UL, 0x335e95505685b963UL, 0xc5a9a1e73e65fe2bUL,
            0x55683446590fce54UL, 0xa39f00f131ef891cUL, 0x8c5f7b7bd058d3afUL, 0x7aa84fccb8b894e7UL,
            0xd3df8c6e133666c9UL, 0x2528b8d97bd62181UL, 0x0ae8c3539a617b32UL, 0xfc1ff7e4f2813c7aUL,
            0xc60e0ac927f490adUL, 0x30f93e7e4f14d7e5UL, 0x1f3945f4aea38d56UL, 0xe9ce7143c643ca1eUL,
            0x40b9b2e16dcd3830UL, 0xb64e8656052d7f78UL, 0x998efddce49a25cbUL, 0x6f79c96b8c7a6283UL,
            0xffb85ccaeb1052fcUL, 0x094f687d83f015b4UL, 0x268f13f762474f07UL, 0xd07827400aa7084fUL,
            0x790fe4e2a129fa61UL, 0x8ff8d055c9c9bd29UL, 0xa038abdf287ee79aUL, 0x56cf9f68409ea0d2UL,
            0xb562a6cebe3d140fUL, 0x43959279d6dd5347UL, 0x6c55e9f3376a09f4UL, 0x9aa2dd445f8a4ebcUL,
            0x33d51ee6f404bc92UL, 0xc5222a519ce4fbdaUL, 0xeae251db7d53a169UL, 0x1c15656c15b3e621UL,
            0x8cd4f0cd72d9d65eUL, 0x7a23c47a1a399116UL, 0x55e3bff0fb8ecba5UL, 0xa3148b47936e8cedUL,
            0x0a6348e538e07ec3UL, 0xfc947c525000398bUL, 0xd35407d8b1b76338UL, 0x25a3336fd9572470UL,
            0x20d752c6146799e9UL, 0xd62066717c87dea1UL, 0xf9e01dfb9d308412UL, 0x0f17294cf5d0c35aUL,
            0xa660eaee5e5e3174UL, 0x5097de5936be763cUL, 0x7f57a5d3d7092c8fUL, 0x89a09164bfe96bc7UL,
            0x196104c5d8835bb8UL, 0xef963072b0631cf0UL, 0xc0564bf851d44643UL, 0x36a17f4f3934010bUL,
            0x9fd6bced92baf325UL, 0x6921885afa5ab46dUL, 0x46e1f3d01bedeedeUL, 0xb016c767730da996UL,
            0x53bbfec18dae1d4bUL, 0xa54cca76e54e5a03UL, 0x8a8cb1fc04f900b0UL, 0x7c7b854b6c1947f8UL,
            0xd50c46e9c797b5d6UL, 0x23fb725eaf77f29eUL, 0x0c3b09d44ec0a82dUL, 0xfacc3d632620ef65UL,
            0x6a0da8c2414adf1aUL, 0x9cfa9c7529aa9852UL, 0xb33ae7ffc81dc2e1UL, 0x45cdd348a0fd85a9UL,
            0xecba10ea0b737787UL, 0x1a4d245d639330cfUL, 0x358d5fd782246a7cUL, 0xc37a6b60eac42d34UL,
            0x3f659c841845114eUL, 0xc992a83370a55606UL, 0xe652d3b991120cb5UL, 0x10a5e70ef9f24bfdUL,
            0xb9d224ac527cb9d3UL, 0x4f25101b3a9cfe9bUL, 0x60e56b91db2ba428UL, 0x96125f26b3cbe360UL,
            0x06d3ca87d4a1d31fUL, 0xf024fe30bc419457UL, 0xdfe485ba5df6cee4UL, 0x2913b10d351689acUL,
            0x806472af9e987b82UL, 0x76934618f6783ccaUL, 0x59533d9217cf6679UL, 0xafa409257f2f2131UL,
            0x4c093083818c95ecUL, 0xbafe0434e96cd2a4UL, 0x953e7fbe08db8817UL, 0x63c94b09603bcf5fUL,
            0xcabe88abcbb53d71UL, 0x3c49bc1ca3557a39UL, 0x1389c79642e2208aUL, 0xe57ef3212a0267c2UL,
            0x75bf66804d6857bdUL, 0x83485237258810f5UL, 0xac8829bdc43f4a46UL, 0x5a7f1d0aacdf0d0eUL,
            0xf308dea80751ff20UL, 0x05ffea1f6fb1b868UL, 0x2a3f91958e06e2dbUL, 0xdcc8a522e6e6a593UL,
            0xd9bcc48b2bd6180aUL, 0x2f4bf03c43365f42UL, 0x008b8bb6a28105f1UL, 0xf67cbf01ca6142b9UL,
            0x5f0b7ca361efb097UL, 0xa9fc4814090ff7dfUL, 0x863c339ee8b8ad6cUL, 0x70cb07298058ea24UL,
            0xe00a9288e732da5bUL, 0x16fda63f8fd29d13UL, 0x393dddb56e65c7a0UL, 0xcfcae902068580e8UL,
            0x66bd2aa0ad0b72c6UL, 0x904a1e17c5eb358eUL, 0xbf8a659d245c6f3dUL, 0x497d512a4cbc2875UL,
            0xaad0688cb21f9ca8UL, 0x5c275c3bdaffdbe0UL, 0x73e727b13b488153UL, 0x8510130653a8c61bUL,
            0x2c67d0a4f8263435UL, 0xda90e41390c6737dUL, 0xf5509f99717129ceUL, 0x03a7ab2e19916e86UL,
            0x93663e8f7efb5ef9UL, 0x65910a38161b19b1UL, 0x4a5171b2f7ac4302UL, 0xbca645059f4c044aUL,
            0x15d186a734c2f664UL, 0xe326b2105c22b12cUL, 0xcce6c99abd95eb9fUL, 0x3a11fd2dd575acd7UL,

            0x0000000000000000UL, 0x71b0c13da512335dUL, 0xe361827b4a2466baUL, 0x92d14346ef3655e7UL,
            0xf21a22a5ccdf5e1fUL, 0x83aae39869cd6d42UL, 0x117ba0de86fb38a5UL, 0x60cb61e323e90bf8UL,
            0xd0ed6318c1292f55UL, 0xa15da225643b1c08UL, 0x338ce1638b0d49efUL, 0x423c205e2e1f7ab2UL,
            0x22f741bd0df6714aUL, 0x53478080a8e44217UL, 0xc196c3c647d217f0UL, 0xb02602fbe2c024adUL,
            0x9503e062dac5cdc1UL, 0xe4b3215f7fd7fe9cUL, 0x7662621990e1ab7bUL, 0x07d2a32435f39826UL,
            0x6719c2c7161a93deUL, 0x16a903fab308a083UL, 0x847840bc5c3ef564UL, 0xf5c88181f92cc639UL,
            0x45ee837a1bece294UL, 0x345e4247befed1c9UL, 0xa68f010151c8842eUL, 0xd73fc03cf4dab773UL,
            0xb7f4a1dfd733bc8bUL, 0xc64460e272218fd6UL, 0x549523a49d17da31UL, 0x2525e2993805e96cUL,
            0x1edee696ed1c08e9UL, 0x6f6e27ab480e3bb4UL, 0xfdbf64eda7386e53UL, 0x8c0fa5d0022a5d0eUL,
            0xecc4c43321c356f6UL, 0x9d74050e84d165abUL, 0x0fa546486be7304cUL, 0x7e158775cef50311UL,
            0xce33858e2c3527bcUL, 0xbf8344b3892714e1UL, 0x2d5207f566114106UL, 0x5ce2c6c8c303725bUL,
            0x3c29a72be0ea79a3UL, 0x4d99661645f84afeUL, 0xdf482550aace1f19UL, 0xaef8e46d0fdc2c44UL,
            0x8bdd06f437d9c528UL, 0xfa6dc7c992cbf675UL, 0x68bc848f7dfda392UL, 0x190c45b2d8ef90cfUL,
            0x79c72451fb069b37UL, 0x0877e56c5e14a86aUL, 0x9aa6a62ab122fd8dUL, 0xeb1667171430ced0UL,
            0x5b3065ecf6f0ea7dUL, 0x2a80a4d153e2d920UL, 0xb851e797bcd48cc7UL, 0xc9e126aa19c6bf9aUL,
            0xa92a47493a2fb462UL, 0xd89a86749f3d873fUL, 0x4a4bc532700bd2d8UL, 0x3bfb040fd519e185UL,
            0x3dbdcd2dda3811d2UL, 0x4c0d0c107f2a228fUL, 0xdedc4f56901c7768UL, 0xaf6c8e6b350e4435UL,
            0xcfa7ef8816e74fcdUL, 0xbe172eb5b3f57c90UL, 0x2cc66df35cc32977UL, 0x5d76accef9d11a2aUL,
            0xed50ae351b113e87UL, 0x9ce06f08be030ddaUL, 0x0e312c4e5135583dUL, 0x7f81ed73f4276b60UL,
            0x1f4a8c90d7ce6098UL, 0x6efa4dad72dc53c5UL, 0xfc2b0eeb9dea0622UL, 0x8d9bcfd638f8357fUL,
            0xa8be2d4f00fddc13UL, 0xd90eec72a5efef4eUL, 0x4bdfaf344ad9baa9UL, 0x3a6f6e09efcb89f4UL,
            0x5aa40feacc22820cUL, 0x2b14ced76930b151UL, 0xb9c58d918606e4b6UL, 0xc8754cac2314d7ebUL,
            0x78534e57c1d4f346UL, 0x09e38f6a64c6c01bUL, 0x9b32cc2c8bf095fcUL, 0xea820d112ee2a6a1UL,
            0x8a496cf20d0bad59UL, 0xfbf9adcfa8199e04UL, 0x6928ee89472fcbe3UL, 0x18982fb4e23df8beUL,
            0x23632bbb3724193bUL, 0x52d3ea8692362a66UL, 0xc002a9c07d007f81UL, 0xb1b268fdd8124cdcUL,
            0xd179091efbfb4724UL, 0xa0c9c8235ee97479UL, 0x32188b65b1df219eUL, 0x43a84a5814cd12c3UL,
            0xf38e48a3f60d366eUL, 0x823e899e531f0533UL, 0x10efcad8bc2950d4UL, 0x615f0be5193b6389UL,
            0x01946a063ad26871UL, 0x7024ab3b9fc05b2cUL, 0xe2f5e87d70f60ecbUL, 0x93452940d5e43d96UL,
            0xb660cbd9ede1d4faUL, 0xc7d00ae448f3e7a7UL, 0x550149a2a7c5b240UL, 0x24b1889f02d7811dUL,
            0x447ae97c213e8ae5UL, 0x35ca2841842cb9b8UL, 0xa71b6b076b1aec5fUL, 0xd6abaa3ace08df02UL,
            0x668da8c12cc8fbafUL, 0x173d69fc89dac8f2UL, 0x85ec2aba66ec9d15UL, 0xf45ceb87c3feae48UL,
            0x94978a64e017a5b0UL, 0xe5274b59450596edUL, 0x77f6081faa33c30aUL, 0x0646c9220f21f057UL,
            0x7b7b9a5bb47023a4UL, 0x0acb5b66116210f9UL, 0x981a1820fe54451eUL, 0xe9aad91d5b467643UL,
            0x8961b8fe78af7dbbUL, 0xf8d179c3ddbd4ee6UL, 0x6a003a85328b1b01UL, 0x1bb0fbb89799285cUL,
            0xab96f94375590cf1UL, 0xda26387ed04b3facUL, 0x48f77b383f7d6a4bUL, 0x3947ba059a6f5916UL,
            0x598cdbe6b98652eeUL, 0x283c1adb1c9461b3UL, 0xbaed599df3a23454UL, 0xcb5d98a056b00709UL,
            0xee787a396eb5ee65UL, 0x9fc8bb04cba7dd38UL, 0x0d19f842249188dfUL, 0x7ca9397f8183bb82UL,
            0x1c62589ca26ab07aUL, 0x6dd299a107788327UL, 0xff03dae7e84ed6c0UL, 0x8eb31bda4d5ce59dUL,
            0x3e951921af9cc130UL, 0x4f25d81c0a8ef26dUL, 0xddf49b5ae5b8a78aUL, 0xac445a6740aa94d7UL,
            0xcc8f3b8463439f2fUL, 0xbd3ffab9c651ac72UL, 0x2feeb9ff2967f995UL, 0x5e5e78c28c75cac8UL,
            0x65a57ccd596c2b4dUL, 0x1415bdf0fc7e1810UL, 0x86c4feb613484df7UL, 0xf7743f8bb65a7eaaUL,
            0x97bf5e6895b37552UL, 0xe60f9f5530a1460fUL, 0x74dedc13df9713e8UL, 0x056e1d2e7a8520b5UL,
            0xb5481fd598450418UL, 0xc4f8dee83d573745UL, 0x56299daed26162a2UL, 0x27995c93777351ffUL,
            0x47523d70549a5a07UL, 0x36e2fc4df188695aUL, 0xa433bf0b1ebe3cbdUL, 0xd5837e36bbac0fe0UL,
            0xf0a69caf83a9e68cUL, 0x81165d9226bbd5d1UL, 0x13c71ed4c98d8036UL, 0x6277dfe96c9fb36bUL,
            0x02bcbe0a4f76b893UL, 0x730c7f37ea648bceUL, 0xe1dd3c710552de29UL, 0x906dfd4ca040ed74UL,
            0x204bffb74280c9d9UL, 0x51fb3e8ae792fa84UL, 0xc32a7dcc08a4af63UL, 0xb29abcf1adb69c3eUL,
            0xd251dd128e5f97c6UL, 0xa3e11c2f2b4da49bUL, 0x31305f69c47bf17cUL, 0x40809e546169c221UL,
            0x46c657766e483276UL, 0x3776964bcb5a012bUL, 0xa5a7d50d246c54ccUL, 0xd4171430817e6791UL,
            0xb4dc75d3a2976c69UL, 0xc56cb4ee07855f34UL, 0x57bdf7a8e8b30ad3UL, 0x260d36954da1398eUL,
            0x962b346eaf611d23UL, 0xe79bf5530a732e7eUL, 0x754ab615e5457b99UL, 0x04fa7728405748c4UL,
            0x643116cb63be433cUL, 0x1581d7f6c6ac7061UL, 0x875094b0299a2586UL, 0xf6e0558d8c8816dbUL,
            0xd3c5b714b48dffb7UL, 0xa2757629119fcceaUL, 0x30a4356ffea9990dUL, 0x4114f4525bbbaa50UL,
            0x21df95b17852a1a8UL, 0x506f548cdd4092f5UL, 0xc2be17ca3276c712UL, 0xb30ed6f79764f44fUL,
            0x0328d40c75a4d0e2UL, 0x72981531d0b6e3bfUL, 0xe04956773f80b658UL, 0x91f9974a9a928505UL,
            0xf132f6a9b97b8efdUL, 0x808237941c69bda0UL, 0x125374d2f35fe847UL, 0x63e3b5ef564ddb1aUL,
            0x5818b1e083543a9fUL, 0x29a870dd264609c2UL, 0xbb79339bc9705c25UL, 0xcac9f2a66c626f78UL,
            0xaa0293454f8b6480UL, 0xdbb25278ea9957ddUL, 0x4963113e05af023aUL, 0x38d3d003a0bd3167UL,
            0x88f5d2f8427d15caUL, 0xf94513c5e76f2697UL, 0x6b94508308597370UL, 0x1a2491bead4b402dUL,
            0x7aeff05d8ea24bd5UL, 0x0b5f31602bb07888UL, 0x998e7226c4862d6fUL, 0xe83eb31b61941e32UL,
            0xcd1b51825991f75eUL, 0xbcab90bffc83c403UL, 0x2e7ad3f913b591e4UL, 0x5fca12c4b6a7a2b9UL,
            0x3f017327954ea941UL, 0x4eb1b21a305c9a1cUL, 0xdc60f15cdf6acffbUL, 0xadd030617a78fca6UL,
            0x1df6329a98b8d80bUL, 0x6c46f3a73daaeb56UL, 0xfe97b0e1d29cbeb1UL, 0x8f2771dc778e8decUL,
            0xefec103f54678614UL, 0x9e5cd102f175b549UL, 0x0c8d92441e43e0aeUL, 0x7d3d5379bb51d3f3UL,

            0x0000000000000000UL, 0xbfdb6c480f15915eUL, 0x4b6ffec346bcb1d7UL, 0xf4b4928b49a92089UL,
            0x96dffd868d7963aeUL, 0x290491ce826cf2f0UL, 0xddb00345cbc5d279UL, 0x626b6f0dc4d04327UL,
            0x1966dd5e42655437UL, 0xa6bdb1164d70c569UL, 0x5209239d04d9e5e0UL, 0xedd24fd50bcc74beUL,
            0x8fb920d8cf1c3799UL, 0x30624c90c009a6c7UL, 0xc4d6de1b89a0864eUL, 0x7b0db25386b51710UL,
            0x32cdbabc84caa86eUL, 0x8d16d6f48bdf3930UL, 0x79a2447fc27619b9UL, 0xc6792837cd6388e7UL,
            0xa412473a09b3cbc0UL, 0x1bc92b7206a65a9eUL, 0xef7db9f94f0f7a17UL, 0x50a6d5b1401aeb49UL,
            0x2bab67e2c6affc59UL, 0x94700baac9ba6d07UL, 0x60c4992180134d8eUL, 0xdf1ff5698f06dcd0UL,
            0xbd749a644bd69ff7UL, 0x02aff62c44c30ea9UL, 0xf61b64a70d6a2e20UL, 0x49c008ef027fbf7eUL,
            0x659b7579099550dcUL, 0xda4019310680c182UL, 0x2ef48bba4f29e10bUL, 0x912fe7f2403c7055UL,
            0xf34488ff84ec3372UL, 0x4c9fe4b78bf9a22cUL, 0xb82b763cc25082a5UL, 0x07f01a74cd4513fbUL,
            0x7cfda8274bf004ebUL, 0xc326c46f44e595b5UL, 0x379256e40d4cb53cUL, 0x88493aac02592462UL,
            0xea2255a1c6896745UL, 0x55f939e9c99cf61bUL, 0xa14dab628035d692UL, 0x1e96c72a8f2047ccUL,
            0x5756cfc58d5ff8b2UL, 0xe88da38d824a69ecUL, 0x1c393106cbe34965UL, 0xa3e25d4ec4f6d83bUL,
            0xc189324300269b1cUL, 0x7e525e0b0f330a42UL, 0x8ae6cc80469a2acbUL, 0x353da0c8498fbb95UL,
            0x4e30129bcf3aac85UL, 0xf1eb7ed3c02f3ddbUL, 0x055fec5889861d52UL, 0xba84801086938c0cUL,
            0xd8efef1d4243cf2bUL, 0x673483554d565e75UL, 0x938011de04ff7efcUL, 0x2c5b7d960beaefa2UL,
            0xcb36eaf2132aa1b8UL, 0x74ed86ba1c3f30e6UL, 0x805914315596106fUL, 0x3f8278795a838131UL,
            0x5de917749e53c216UL, 0xe2327b3c91465348UL, 0x1686e9b7d8ef73c1UL, 0xa95d85ffd7fae29fUL,
            0xd25037ac514ff58fUL, 0x6d8b5be45e5a64d1UL, 0x993fc96f17f34458UL, 0x26e4a52718e6d506UL,
            0x448fca2adc369621UL, 0xfb54a662d323077fUL, 0x0fe034e99a8a27f6UL, 0xb03b58a1959fb6a8UL,
            0xf9fb504e97e009d6UL, 0x46203c0698f59888UL, 0xb294ae8dd15cb801UL, 0x0d4fc2c5de49295fUL,
            0x6f24adc81a996a78UL, 0xd0ffc180158cfb26UL, 0x244b530b5c25dbafUL, 0x9b903f4353304af1UL,
            0xe09d8d10d5855de1UL, 0x5f46e158da90ccbfUL, 0xabf273d39339ec36UL, 0x14291f9b9c2c7d68UL,
            0x7642709658fc3e4fUL, 0xc9991cde57e9af11UL, 0x3d2d8e551e408f98UL, 0x82f6e21d11551ec6UL,
            0xaead9f8b1abff164UL, 0x1176f3c315aa603aUL, 0xe5c261485c0340b3UL, 0x5a190d005316d1edUL,
            0x3872620d97c692caUL, 0x87a90e4598d30394UL, 0x731d9cced17a231dUL, 0xccc6f086de6fb243UL,
            0xb7cb42d558daa553UL, 0x08102e9d57cf340dUL, 0xfca4bc161e661484UL, 0x437fd05e117385daUL,
            0x2114bf53d5a3c6fdUL, 0x9ecfd31bdab657a3UL, 0x6a7b4190931f772aUL, 0xd5a02dd89c0ae674UL,
            0x9c6025379e75590aUL, 0x23bb497f9160c854UL, 0xd70fdbf4d8c9e8ddUL, 0x68d4b7bcd7dc7983UL,
            0x0abfd8b1130c3aa4UL, 0xb564b4f91c19abfaUL, 0x41d0267255b08b73UL, 0xfe0b4a3a5aa51a2dUL,
            0x8506f869dc100d3dUL, 0x3add9421d3059c63UL, 0xce6906aa9aacbceaUL, 0x71b26ae295b92db4UL,
            0x13d905ef51696e93UL, 0xac0269a75e7cffcdUL, 0x58b6fb2c17d5df44UL, 0xe76d976418c04e1aUL,
            0xa2b4f3b77ec2d01bUL, 0x1d6f9fff71d74145UL, 0xe9db0d74387e61ccUL, 0x5600613c376bf092UL,
            0x346b0e31f3bbb3b5UL, 0x8bb06279fcae22ebUL, 0x7f04f0f2b5070262UL, 0xc0df9cbaba12933cUL,
            0xbbd22ee93ca7842cUL, 0x040942a133b21572UL, 0xf0bdd02a7a1b35fbUL, 0x4f66bc62750ea4a5UL,
            0x2d0dd36fb1dee782UL, 0x92d6bf27becb76dcUL, 0x66622dacf7625655UL, 0xd9b941e4f877c70bUL,
            0x9079490bfa087875UL, 0x2fa22543f51de92bUL, 0xdb16b7c8bcb4c9a2UL, 0x64cddb80b3a158fcUL,
            0x06a6b48d77711bdbUL, 0xb97dd8c578648a85UL, 0x4dc94a4e31cdaa0cUL, 0xf21226063ed83b52UL,
            0x891f9455b86d2c42UL, 0x36c4f81db778bd1cUL, 0xc2706a96fed19d95UL, 0x7dab06def1c40ccbUL,
            0x1fc069d335144fecUL, 0xa01b059b3a01deb2UL, 0x54af971073a8fe3bUL, 0xeb74fb587cbd6f65UL,
            0xc72f86ce775780c7UL, 0x78f4ea8678421199UL, 0x8c40780d31eb3110UL, 0x339b14453efea04eUL,
            0x51f07b48fa2ee369UL, 0xee2b1700f53b7237UL, 0x1a9f858bbc9252beUL, 0xa544e9c3b387c3e0UL,
            0xde495b903532d4f0UL, 0x619237d83a2745aeUL, 0x9526a553738e6527UL, 0x2afdc91b7c9bf479UL,
            0x4896a616b84bb75eUL, 0xf74dca5eb75e2600UL, 0x03f958d5fef70689UL, 0xbc22349df1e297d7UL,
            0xf5e23c72f39d28a9UL, 0x4a39503afc88b9f7UL, 0xbe8dc2b1b521997eUL, 0x0156aef9ba340820UL,
            0x633dc1f47ee44b07UL, 0xdce6adbc71f1da59UL, 0x28523f373858fad0UL, 0x9789537f374d6b8eUL,
            0xec84e12cb1f87c9eUL, 0x535f8d64beededc0UL, 0xa7eb1feff744cd49UL, 0x183073a7f8515c17UL,
            0x7a5b1caa3c811f30UL, 0xc58070e233948e6eUL, 0x3134e2697a3daee7UL, 0x8eef8e2175283fb9UL,
            0x698219456de871a3UL, 0xd659750d62fde0fdUL, 0x22ede7862b54c074UL, 0x9d368bce2441512aUL,
            0xff5de4c3e091120dUL, 0x4086888bef848353UL, 0xb4321a00a62da3daUL, 0x0be97648a9383284UL,
            0x70e4c41b2f8d2594UL, 0xcf3fa8532098b4caUL, 0x3b8b3ad869319443UL, 0x845056906624051dUL,
            0xe63b399da2f4463aUL, 0x59e055d5ade1d764UL, 0xad54c75ee448f7edUL, 0x128fab16eb5d66b3UL,
            0x5b4fa3f9e922d9cdUL, 0xe494cfb1e6374893UL, 0x10205d3aaf9e681aUL, 0xaffb3172a08bf944UL,
            0xcd905e7f645bba63UL, 0x724b32376b4e2b3dUL, 0x86ffa0bc22e70bb4UL, 0x3924ccf42df29aeaUL,
            0x42297ea7ab478dfaUL, 0xfdf212efa4521ca4UL, 0x09468064edfb3c2dUL, 0xb69dec2ce2eead73UL,
            0xd4f68321263eee54UL, 0x6b2def69292b7f0aUL, 0x9f997de260825f83UL, 0x204211aa6f97ceddUL,
            0x0c196c3c647d217fUL, 0xb3c200746b68b021UL, 0x477692ff22c190a8UL, 0xf8adfeb72dd401f6UL,
            0x9ac691bae90442d1UL, 0x251dfdf2e611d38fUL, 0xd1a96f79afb8f306UL, 0x6e720331a0ad6258UL,
            0x157fb16226187548UL, 0xaaa4dd2a290de416UL, 0x5e104fa160a4c49fUL, 0xe1cb23e96fb155c1UL,
            0x83a04ce4ab6116e6UL, 0x3c7b20aca47487b8UL, 0xc8cfb227eddda731UL, 0x7714de6fe2c8366fUL,
            0x3ed4d680e0b78911UL, 0x810fbac8efa2184fUL, 0x75bb2843a60b38c6UL, 0xca60440ba91ea998UL,
            0xa80b2b066dceeabfUL, 0x17d0474e62db7be1UL, 0xe364d5c52b725b68UL, 0x5cbfb98d2467ca36UL,
            0x27b20bdea2d2dd26UL, 0x98696796adc74c78UL, 0x6cddf51de46e6cf1UL, 0xd3069955eb7bfdafUL,
            0xb16df6582fabbe88UL, 0x0eb69a1020be2fd6UL, 0xfa02089b69170f5fUL, 0x45d964d366029e01UL,

            0x0000000000000000UL, 0x3ea616bd2ae10d77UL, 0x7d4c2d7a55c21aeeUL, 0x43ea3bc77f231799UL,
            0xfa985af4ab8435dcUL, 0xc43e4c49816538abUL, 0x87d4778efe462f32UL, 0xb9726133d4a72245UL,
            0xc1e993ba0f9ff8d3UL, 0xff4f8507257ef5a4UL, 0xbca5bec05a5de23dUL, 0x8203a87d70bcef4aUL,
            0x3b71c94ea41bcd0fUL, 0x05d7dff38efac078UL, 0x463de434f1d9d7e1UL, 0x789bf289db38da96UL,
            0xb70a012747a862cdUL, 0x89ac179a6d496fbaUL, 0xca462c5d126a7823UL, 0xf4e03ae0388b7554UL,
            0x4d925bd3ec2c5711UL, 0x73344d6ec6cd5a66UL, 0x30de76a9b9ee4dffUL, 0x0e786014930f4088UL,
            0x76e3929d48379a1eUL, 0x4845842062d69769UL, 0x0bafbfe71df580f0UL, 0x3509a95a37148d87UL,
            0x8c7bc869e3b3afc2UL, 0xb2ddded4c952a2b5UL, 0xf137e513b671b52cUL, 0xcf91f3ae9c90b85bUL,
            0x5acd241dd7c756f1UL, 0x646b32a0fd265b86UL, 0x2781096782054c1fUL, 0x19271fdaa8e44168UL,
            0xa0557ee97c43632dUL, 0x9ef3685456a26e5aUL, 0xdd195393298179c3UL, 0xe3bf452e036074b4UL,
            0x9b24b7a7d858ae22UL, 0xa582a11af2b9a355UL, 0xe6689add8d9ab4ccUL, 0xd8ce8c60a77bb9bbUL,
            0x61bced5373dc9bfeUL, 0x5f1afbee593d9689UL, 0x1cf0c029261e8110UL, 0x2256d6940cff8c67UL,
            0xedc7253a906f343cUL, 0xd3613387ba8e394bUL, 0x908b0840c5ad2ed2UL, 0xae2d1efdef4c23a5UL,
            0x175f7fce3beb01e0UL, 0x29f96973110a0c97UL, 0x6a1352b46e291b0eUL, 0x54b5440944c81679UL,
            0x2c2eb6809ff0ccefUL, 0x1288a03db511c198UL, 0x51629bfaca32d601UL, 0x6fc48d47e0d3db76UL,
            0xd6b6ec743474f933UL, 0xe810fac91e95f444UL, 0xabfac10e61b6e3ddUL, 0x955cd7b34b57eeaaUL,
            0xb59a483baf8eade2UL, 0x8b3c5e86856fa095UL, 0xc8d66541fa4cb70cUL, 0xf67073fcd0adba7bUL,
            0x4f0212cf040a983eUL, 0x71a404722eeb9549UL, 0x324e3fb551c882d0UL, 0x0ce829087b298fa7UL,
            0x7473db81a0115531UL, 0x4ad5cd3c8af05846UL, 0x093ff6fbf5d34fdfUL, 0x3799e046df3242a8UL,
            0x8eeb81750b9560edUL, 0xb04d97c821746d9aUL, 0xf3a7ac0f5e577a03UL, 0xcd01bab274b67774UL,
            0x0290491ce826cf2fUL, 0x3c365fa1c2c7c258UL, 0x7fdc6466bde4d5c1UL, 0x417a72db9705d8b6UL,
            0xf80813e843a2faf3UL, 0xc6ae05556943f784UL, 0x85443e921660e01dUL, 0xbbe2282f3c81ed6aUL,
            0xc379daa6e7b937fcUL, 0xfddfcc1bcd583a8bUL, 0xbe35f7dcb27b2d12UL, 0x8093e161989a2065UL,
            0x39e180524c3d0220UL, 0x074796ef66dc0f57UL, 0x44adad2819ff18ceUL, 0x7a0bbb95331e15b9UL,
            0xef576c267849fb13UL, 0xd1f17a9b52a8f664UL, 0x921b415c2d8be1fdUL, 0xacbd57e1076aec8aUL,
            0x15cf36d2d3cdcecfUL, 0x2b69206ff92cc3b8UL, 0x68831ba8860fd421UL, 0x56250d15aceed956UL,
            0x2ebeff9c77d603c0UL, 0x1018e9215d370eb7UL, 0x53f2d2e62214192eUL, 0x6d54c45b08f51459UL,
            0xd426a568dc52361cUL, 0xea80b3d5f6b33b6bUL, 0xa96a881289902cf2UL, 0x97cc9eafa3712185UL,
            0x585d6d013fe199deUL, 0x66fb7bbc150094a9UL, 0x2511407b6a238330UL, 0x1bb756c640c28e47UL,
            0xa2c537f59465ac02UL, 0x9c632148be84a175UL, 0xdf891a8fc1a7b6ecUL, 0xe12f0c32eb46bb9bUL,
            0x99b4febb307e610dUL, 0xa712e8061a9f6c7aUL, 0xe4f8d3c165bc7be3UL, 0xda5ec57c4f5d7694UL,
            0x632ca44f9bfa54d1UL, 0x5d8ab2f2b11b59a6UL, 0x1e608935ce384e3fUL, 0x20c69f88e4d94348UL,
            0x5fedb624078ac8afUL, 0x614ba0992d6bc5d8UL, 0x22a19b5e5248d241UL, 0x1c078de378a9df36UL,
            0xa575ecd0ac0efd73UL, 0x9bd3fa6d86eff004UL, 0xd839c1aaf9cce79dUL, 0xe69fd717d32deaeaUL,
            0x9e04259e0815307cUL, 0xa0a2332322f43d0bUL, 0xe34808e45dd72a92UL, 0xddee1e59773627e5UL,
            0x649c7f6aa39105a0UL, 0x5a3a69d7897008d7UL, 0x19d05210f6531f4eUL, 0x277644addcb21239UL,
            0xe8e7b7034022aa62UL, 0xd641a1be6ac3a715UL, 0x95ab9a7915e0b08cUL, 0xab0d8cc43f01bdfbUL,
            0x127fedf7eba69fbeUL, 0x2cd9fb4ac14792c9UL, 0x6f33c08dbe648550UL, 0x5195d63094858827UL,
            0x290e24b94fbd52b1UL, 0x17a83204655c5fc6UL, 0x544209c31a7f485fUL, 0x6ae41f7e309e4528UL,
            0xd3967e4de439676dUL, 0xed3068f0ced86a1aUL, 0xaeda5337b1fb7d83UL, 0x907c458a9b1a70f4UL,
            0x05209239d04d9e5eUL, 0x3b868484faac9329UL, 0x786cbf43858f84b0UL, 0x46caa9feaf6e89c7UL,
            0xffb8c8cd7bc9ab82UL, 0xc11ede705128a6f5UL, 0x82f4e5b72e0bb16cUL, 0xbc52f30a04eabc1bUL,
            0xc4c90183dfd2668dUL, 0xfa6f173ef5336bfaUL, 0xb9852cf98a107c63UL, 0x87233a44a0f17114UL,
            0x3e515b7774565351UL, 0x00f74dca5eb75e26UL, 0x431d760d219449bfUL, 0x7dbb60b00b7544c8UL,
            0xb22a931e97e5fc93UL, 0x8c8c85a3bd04f1e4UL, 0xcf66be64c227e67dUL, 0xf1c0a8d9e8c6eb0aUL,
            0x48b2c9ea3c61c94fUL, 0x7614df571680c438UL, 0x35fee49069a3d3a1UL, 0x0b58f22d4342ded6UL,
            0x73c300a4987a0440UL, 0x4d651619b29b0937UL, 0x0e8f2ddecdb81eaeUL, 0x30293b63e75913d9UL,
            0x895b5a5033fe319cUL, 0xb7fd4ced191f3cebUL, 0xf417772a663c2b72UL, 0xcab161974cdd2605UL,
            0xea77fe1fa804654dUL, 0xd4d1e8a282e5683aUL, 0x973bd365fdc67fa3UL, 0xa99dc5d8d72772d4UL,
            0x10efa4eb03805091UL, 0x2e49b25629615de6UL, 0x6da3899156424a7fUL, 0x53059f2c7ca34708UL,
            0x2b9e6da5a79b9d9eUL, 0x15387b188d7a90e9UL, 0x56d240dff2598770UL, 0x68745662d8b88a07UL,
            0xd10637510c1fa842UL, 0xefa021ec26fea535UL, 0xac4a1a2b59ddb2acUL, 0x92ec0c96733cbfdbUL,
            0x5d7dff38efac0780UL, 0x63dbe985c54d0af7UL, 0x2031d242ba6e1d6eUL, 0x1e97c4ff908f1019UL,
            0xa7e5a5cc4428325cUL, 0x9943b3716ec93f2bUL, 0xdaa988b611ea28b2UL, 0xe40f9e0b3b0b25c5UL,
            0x9c946c82e033ff53UL, 0xa2327a3fcad2f224UL, 0xe1d841f8b5f1e5bdUL, 0xdf7e57459f10e8caUL,
            0x660c36764bb7ca8fUL, 0x58aa20cb6156c7f8UL, 0x1b401b0c1e75d061UL, 0x25e60db13494dd16UL,
            0xb0bada027fc333bcUL, 0x8e1cccbf55223ecbUL, 0xcdf6f7782a012952UL, 0xf350e1c500e02425UL,
            0x4a2280f6d4470660UL, 0x7484964bfea60b17UL, 0x376ead8c81851c8eUL, 0x09c8bb31ab6411f9UL,
            0x715349b8705ccb6fUL, 0x4ff55f055abdc618UL, 0x0c1f64c2259ed181UL, 0x32b9727f0f7fdcf6UL,
            0x8bcb134cdbd8feb3UL, 0xb56d05f1f139f3c4UL, 0xf6873e368e1ae45dUL, 0xc821288ba4fbe92aUL,
            0x07b0db25386b5171UL, 0x3916cd98128a5c06UL, 0x7afcf65f6da94b9fUL, 0x445ae0e2474846e8UL,
            0xfd2881d193ef64adUL, 0xc38e976cb90e69daUL, 0x8064acabc62d7e43UL, 0xbec2ba16eccc7334UL,
            0xc659489f37f4a9a2UL, 0xf8ff5e221d15a4d5UL, 0xbb1565e56236b34cUL, 0x85b3735848d7be3bUL,
            0x3cc1126b9c709c7eUL, 0x026704d6b6919109UL, 0x418d3f11c9b28690UL, 0x7f2b29ace3538be7UL,

            0x0000000000000000UL, 0x169489cc969951e5UL, 0x2d2913992d32a3caUL, 0x3bbd9a55bbabf22fUL,
            0x5a5227325a654794UL, 0x4cc6aefeccfc1671UL, 0x777b34ab7757e45eUL, 0x61efbd67e1ceb5bbUL,
            0xb4a44e64b4ca8f28UL, 0xa230c7a82253decdUL, 0x998d5dfd99f82ce2UL, 0x8f19d4310f617d07UL,
            0xeef66956eeafc8bcUL, 0xf862e09a78369959UL, 0xc3df7acfc39d6b76UL, 0xd54bf30355043a93UL,
            0x5d91ba9a31028d3bUL, 0x4b053356a79bdcdeUL, 0x70b8a9031c302ef1UL, 0x662c20cf8aa97f14UL,
            0x07c39da86b67caafUL, 0x11571464fdfe9b4aUL, 0x2aea8e3146556965UL, 0x3c7e07fdd0cc3880UL,
            0xe935f4fe85c80213UL, 0xffa17d32135153f6UL, 0xc41ce767a8faa1d9UL, 0xd2886eab3e63f03cUL,
            0xb367d3ccdfad4587UL, 0xa5f35a0049341462UL, 0x9e4ec055f29fe64dUL, 0x88da49996406b7a8UL,
            0xbb23753462051a76UL, 0xadb7fcf8f49c4b93UL, 0x960a66ad4f37b9bcUL, 0x809eef61d9aee859UL,
            0xe171520638605de2UL, 0xf7e5dbcaaef90c07UL, 0xcc58419f1552fe28UL, 0xdaccc85383cbafcdUL,
            0x0f873b50d6cf955eUL, 0x1913b29c4056c4bbUL, 0x22ae28c9fbfd3694UL, 0x343aa1056d646771UL,
            0x55d51c628caad2caUL, 0x434195ae1a33832fUL, 0x78fc0ffba1987100UL, 0x6e688637370120e5UL,
            0xe6b2cfae5307974dUL, 0xf0264662c59ec6a8UL, 0xcb9bdc377e353487UL, 0xdd0f55fbe8ac6562UL,
            0xbce0e89c0962d0d9UL, 0xaa7461509ffb813cUL, 0x91c9fb0524507313UL, 0x875d72c9b2c922f6UL,
            0x521681cae7cd1865UL, 0x4482080671544980UL, 0x7f3f9253caffbbafUL, 0x69ab1b9f5c66ea4aUL,
            0x0844a6f8bda85ff1UL, 0x1ed02f342b310e14UL, 0x256db561909afc3bUL, 0x33f93cad0603addeUL,
            0x429fcc3b9c9da787UL, 0x540b45f70a04f662UL, 0x6fb6dfa2b1af044dUL, 0x7922566e273655a8UL,
            0x18cdeb09c6f8e013UL, 0x0e5962c55061b1f6UL, 0x35e4f890ebca43d9UL, 0x2370715c7d53123cUL,
            0xf63b825f285728afUL, 0xe0af0b93bece794aUL, 0xdb1291c605658b65UL, 0xcd86180a93fcda80UL,
            0xac69a56d72326f3bUL, 0xbafd2ca1e4ab3edeUL, 0x8140b6f45f00ccf1UL, 0x97d43f38c9999d14UL,
            0x1f0e76a1ad9f2abcUL, 0x099aff6d3b067b59UL, 0x3227653880ad8976UL, 0x24b3ecf41634d893UL,
            0x455c5193f7fa6d28UL, 0x53c8d85f61633ccdUL, 0x6875420adac8cee2UL, 0x7ee1cbc64c519f07UL,
            0xabaa38c51955a594UL, 0xbd3eb1098fccf471UL, 0x86832b5c3467065eUL, 0x9017a290a2fe57bbUL,
            0xf1f81ff74330e200UL, 0xe76c963bd5a9b3e5UL, 0xdcd10c6e6e0241caUL, 0xca4585a2f89b102fUL,
            0xf9bcb90ffe98bdf1UL, 0xef2830c36801ec14UL, 0xd495aa96d3aa1e3bUL, 0xc201235a45334fdeUL,
            0xa3ee9e3da4fdfa65UL, 0xb57a17f13264ab80UL, 0x8ec78da489cf59afUL, 0x985304681f56084aUL,
            0x4d18f76b4a5232d9UL, 0x5b8c7ea7dccb633cUL, 0x6031e4f267609113UL, 0x76a56d3ef1f9c0f6UL,
            0x174ad0591037754dUL, 0x01de599586ae24a8UL, 0x3a63c3c03d05d687UL, 0x2cf74a0cab9c8762UL,
            0xa42d0395cf9a30caUL, 0xb2b98a595903612fUL, 0x8904100ce2a89300UL, 0x9f9099c07431c2e5UL,
            0xfe7f24a795ff775eUL, 0xe8ebad6b036626bbUL, 0xd356373eb8cdd494UL, 0xc5c2bef22e548571UL,
            0x10894df17b50bfe2UL, 0x061dc43dedc9ee07UL, 0x3da05e6856621c28UL, 0x2b34d7a4c0fb4dcdUL,
            0x4adb6ac32135f876UL, 0x5c4fe30fb7aca993UL, 0x67f2795a0c075bbcUL, 0x7166f0969a9e0a59UL,
            0x853f9877393b4f0eUL, 0x93ab11bbafa21eebUL, 0xa8168bee1409ecc4UL, 0xbe8202228290bd21UL,
            0xdf6dbf45635e089aUL, 0xc9f93689f5c7597fUL, 0xf244acdc4e6cab50UL, 0xe4d02510d8f5fab5UL,
            0x319bd6138df1c026UL, 0x270f5fdf1b6891c3UL, 0x1cb2c58aa0c363ecUL, 0x0a264c46365a3209UL,
            0x6bc9f121d79487b2UL, 0x7d5d78ed410dd657UL, 0x46e0e2b8faa62478UL, 0x50746b746c3f759dUL,
            0xd8ae22ed0839c235UL, 0xce3aab219ea093d0UL, 0xf5873174250b61ffUL, 0xe313b8b8b392301aUL,
            0x82fc05df525c85a1UL, 0x94688c13c4c5d444UL, 0xafd516467f6e266bUL, 0xb9419f8ae9f7778eUL,
            0x6c0a6c89bcf34d1dUL, 0x7a9ee5452a6a1cf8UL, 0x41237f1091c1eed7UL, 0x57b7f6dc0758bf32UL,
            0x36584bbbe6960a89UL, 0x20ccc277700f5b6cUL, 0x1b715822cba4a943UL, 0x0de5d1ee5d3df8a6UL,
            0x3e1ced435b3e5578UL, 0x2888648fcda7049dUL, 0x1335feda760cf6b2UL, 0x05a17716e095a757UL,
            0x644eca71015b12ecUL, 0x72da43bd97c24309UL, 0x4967d9e82c69b126UL, 0x5ff35024baf0e0c3UL,
            0x8ab8a327eff4da50UL, 0x9c2c2aeb796d8bb5UL, 0xa791b0bec2c6799aUL, 0xb1053972545f287fUL,
            0xd0ea8415b5919dc4UL, 0xc67e0dd92308cc21UL, 0xfdc3978c98a33e0eUL, 0xeb571e400e3a6febUL,
            0x638d57d96a3cd843UL, 0x7519de15fca589a6UL, 0x4ea44440470e7b89UL, 0x5830cd8cd1972a6cUL,
            0x39df70eb30599fd7UL, 0x2f4bf927a6c0ce32UL, 0x14f663721d6b3c1dUL, 0x0262eabe8bf26df8UL,
            0xd72919bddef6576bUL, 0xc1bd9071486f068eUL, 0xfa000a24f3c4f4a1UL, 0xec9483e8655da544UL,
            0x8d7b3e8f849310ffUL, 0x9befb743120a411aUL, 0xa0522d16a9a1b335UL, 0xb6c6a4da3f38e2d0UL,
            0xc7a0544ca5a6e889UL, 0xd134dd80333fb96cUL, 0xea8947d588944b43UL, 0xfc1dce191e0d1aa6UL,
            0x9df2737effc3af1dUL, 0x8b66fab2695afef8UL, 0xb0db60e7d2f10cd7UL, 0xa64fe92b44685d32UL,
            0x73041a28116c67a1UL, 0x659093e487f53644UL, 0x5e2d09b13c5ec46bUL, 0x48b9807daac7958eUL,
            0x29563d1a4b092035UL, 0x3fc2b4d6dd9071d0UL, 0x047f2e83663b83ffUL, 0x12eba74ff0a2d21aUL,
            0x9a31eed694a465b2UL, 0x8ca5671a023d3457UL, 0xb718fd4fb996c678UL, 0xa18c74832f0f979dUL,
            0xc063c9e4cec12226UL, 0xd6f74028585873c3UL, 0xed4ada7de3f381ecUL, 0xfbde53b1756ad009UL,
            0x2e95a0b2206eea9aUL, 0x3801297eb6f7bb7fUL, 0x03bcb32b0d5c4950UL, 0x15283ae79bc518b5UL,
            0x74c787807a0bad0eUL, 0x62530e4cec92fcebUL, 0x59ee941957390ec4UL, 0x4f7a1dd5c1a05f21UL,
            0x7c832178c7a3f2ffUL, 0x6a17a8b4513aa31aUL, 0x51aa32e1ea915135UL, 0x473ebb2d7c0800d0UL,
            0x26d1064a9dc6b56bUL, 0x30458f860b5fe48eUL, 0x0bf815d3b0f416a1UL, 0x1d6c9c1f266d4744UL,
            0xc8276f1c73697dd7UL, 0xdeb3e6d0e5f02c32UL, 0xe50e7c855e5bde1dUL, 0xf39af549c8c28ff8UL,
            0x9275482e290c3a43UL, 0x84e1c1e2bf956ba6UL, 0xbf5c5bb7043e9989UL, 0xa9c8d27b92a7c86cUL,
            0x21129be2f6a17fc4UL, 0x3786122e60382e21UL, 0x0c3b887bdb93dc0eUL, 0x1aaf01b74d0a8debUL,
            0x7b40bcd0acc43850UL, 0x6dd4351c3a5d69b5UL, 0x5669af4981f69b9aUL, 0x40fd2685176fca7fUL,
            0x95b6d586426bf0ecUL, 0x83225c4ad4f2a109UL, 0xb89fc61f6f595326UL, 0xae0b4fd3f9c002c3UL,
            0xcfe4f2b4180eb778UL, 0xd9707b788e97e69dUL, 0xe2cde12d353c14b2UL, 0xf45968e1a3a54557UL,

            0x0000000000000000UL, 0x0aed36d1a3bb9d7fUL, 0x15da6da347773afeUL, 0x1f375b72e4cca781UL,
            0x2bb4db468eee75fcUL, 0x2159ed972d55e883UL, 0x3e6eb6e5c9994f02UL, 0x348380346a22d27dUL,
            0x5769b68d1ddcebf8UL, 0x5d84805cbe677687UL, 0x42b3db2e5aabd106UL, 0x485eedfff9104c79UL,
            0x7cdd6dcb93329e04UL, 0x76305b1a3089037bUL, 0x69070068d445a4faUL, 0x63ea36b977fe3985UL,
            0xaed36d1a3bb9d7f0UL, 0xa43e5bcb98024a8fUL, 0xbb0900b97cceed0eUL, 0xb1e43668df757071UL,
            0x8567b65cb557a20cUL, 0x8f8a808d16ec3f73UL, 0x90bddbfff22098f2UL, 0x9a50ed2e519b058dUL,
            0xf9badb9726653c08UL, 0xf357ed4685dea177UL, 0xec60b634611206f6UL, 0xe68d80e5c2a99b89UL,
            0xd20e00d1a88b49f4UL, 0xd8e336000b30d48bUL, 0xc7d46d72effc730aUL, 0xcd395ba34c47ee75UL,
            0x697ffc672fe43c8bUL, 0x6392cab68c5fa1f4UL, 0x7ca591c468930675UL, 0x7648a715cb289b0aUL,
            0x42cb2721a10a4977UL, 0x482611f002b1d408UL, 0x57114a82e67d7389UL, 0x5dfc7c5345c6eef6UL,
            0x3e164aea3238d773UL, 0x34fb7c3b91834a0cUL, 0x2bcc2749754fed8dUL, 0x21211198d6f470f2UL,
            0x15a291acbcd6a28fUL, 0x1f4fa77d1f6d3ff0UL, 0x0078fc0ffba19871UL, 0x0a95cade581a050eUL,
            0xc7ac917d145deb7bUL, 0xcd41a7acb7e67604UL, 0xd276fcde532ad185UL, 0xd89bca0ff0914cfaUL,
            0xec184a3b9ab39e87UL, 0xe6f57cea390803f8UL, 0xf9c22798ddc4a479UL, 0xf32f11497e7f3906UL,
            0x90c527f009810083UL, 0x9a281121aa3a9dfcUL, 0x851f4a534ef63a7dUL, 0x8ff27c82ed4da702UL,
            0xbb71fcb6876f757fUL, 0xb19cca6724d4e800UL, 0xaeab9115c0184f81UL, 0xa446a7c463a3d2feUL,
            0xd2fff8ce5fc87916UL, 0xd812ce1ffc73e469UL, 0xc725956d18bf43e8UL, 0xcdc8a3bcbb04de97UL,
            0xf94b2388d1260ceaUL, 0xf3a61559729d9195UL, 0xec914e2b96513614UL, 0xe67c78fa35eaab6bUL,
            0x85964e43421492eeUL, 0x8f7b7892e1af0f91UL, 0x904c23e00563a810UL, 0x9aa11531a6d8356fUL,
            0xae229505ccfae712UL, 0xa4cfa3d46f417a6dUL, 0xbbf8f8a68b8dddecUL, 0xb115ce7728364093UL,
            0x7c2c95d46471aee6UL, 0x76c1a305c7ca3399UL, 0x69f6f87723069418UL, 0x631bcea680bd0967UL,
            0x57984e92ea9fdb1aUL, 0x5d75784349244665UL, 0x42422331ade8e1e4UL, 0x48af15e00e537c9bUL,
            0x2b45235979ad451eUL, 0x21a81588da16d861UL, 0x3e9f4efa3eda7fe0UL, 0x3472782b9d61e29fUL,
            0x00f1f81ff74330e2UL, 0x0a1ccece54f8ad9dUL, 0x152b95bcb0340a1cUL, 0x1fc6a36d138f9763UL,
            0xbb8004a9702c459dUL, 0xb16d3278d397d8e2UL, 0xae5a690a375b7f63UL, 0xa4b75fdb94e0e21cUL,
            0x9034dfeffec23061UL, 0x9ad9e93e5d79ad1eUL, 0x85eeb24cb9b50a9fUL, 0x8f03849d1a0e97e0UL,
            0xece9b2246df0ae65UL, 0xe60484f5ce4b331aUL, 0xf933df872a87949bUL, 0xf3dee956893c09e4UL,
            0xc75d6962e31edb99UL, 0xcdb05fb340a546e6UL, 0xd28704c1a469e167UL, 0xd86a321007d27c18UL,
            0x155369b34b95926dUL, 0x1fbe5f62e82e0f12UL, 0x008904100ce2a893UL, 0x0a6432c1af5935ecUL,
            0x3ee7b2f5c57be791UL, 0x340a842466c07aeeUL, 0x2b3ddf56820cdd6fUL, 0x21d0e98721b74010UL,
            0x423adf3e56497995UL, 0x48d7e9eff5f2e4eaUL, 0x57e0b29d113e436bUL, 0x5d0d844cb285de14UL,
            0x698e0478d8a70c69UL, 0x636332a97b1c9116UL, 0x7c5469db9fd03697UL, 0x76b95f0a3c6babe8UL,
            0x9126d7cfe7076147UL, 0x9bcbe11e44bcfc38UL, 0x84fcba6ca0705bb9UL, 0x8e118cbd03cbc6c6UL,
            0xba920c8969e914bbUL, 0xb07f3a58ca5289c4UL, 0xaf48612a2e9e2e45UL, 0xa5a557fb8d25b33aUL,
            0xc64f6142fadb8abfUL, 0xcca25793596017c0UL, 0xd3950ce1bdacb041UL, 0xd9783a301e172d3eUL,
            0xedfbba047435ff43UL, 0xe7168cd5d78e623cUL, 0xf821d7a73342c5bdUL, 0xf2cce17690f958c2UL,
            0x3ff5bad5dcbeb6b7UL, 0x35188c047f052bc8UL, 0x2a2fd7769bc98c49UL, 0x20c2e1a738721136UL,
            0x144161935250c34bUL, 0x1eac5742f1eb5e34UL, 0x019b0c301527f9b5UL, 0x0b763ae1b69c64caUL,
            0x689c0c58c1625d4fUL, 0x62713a8962d9c030UL, 0x7d4661fb861567b1UL, 0x77ab572a25aefaceUL,
            0x4328d71e4f8c28b3UL, 0x49c5e1cfec37b5ccUL, 0x56f2babd08fb124dUL, 0x5c1f8c6cab408f32UL,
            0xf8592ba8c8e35dccUL, 0xf2b41d796b58c0b3UL, 0xed83460b8f946732UL, 0xe76e70da2c2ffa4dUL,
            0xd3edf0ee460d2830UL, 0xd900c63fe5b6b54fUL, 0xc6379d4d017a12ceUL, 0xccdaab9ca2c18fb1UL,
            0xaf309d25d53fb634UL, 0xa5ddabf476842b4bUL, 0xbaeaf08692488ccaUL, 0xb007c65731f311b5UL,
            0x848446635bd1c3c8UL, 0x8e6970b2f86a5eb7UL, 0x915e2bc01ca6f936UL, 0x9bb31d11bf1d6449UL,
            0x568a46b2f35a8a3cUL, 0x5c67706350e11743UL, 0x43502b11b42db0c2UL, 0x49bd1dc017962dbdUL,
            0x7d3e9df47db4ffc0UL, 0x77d3ab25de0f62bfUL, 0x68e4f0573ac3c53eUL, 0x6209c68699785841UL,
            0x01e3f03fee8661c4UL, 0x0b0ec6ee4d3dfcbbUL, 0x14399d9ca9f15b3aUL, 0x1ed4ab4d0a4ac645UL,
            0x2a572b7960681438UL, 0x20ba1da8c3d38947UL, 0x3f8d46da271f2ec6UL, 0x3560700b84a4b3b9UL,
            0x43d92f01b8cf1851UL, 0x493419d01b74852eUL, 0x560342a2ffb822afUL, 0x5cee74735c03bfd0UL,
            0x686df44736216dadUL, 0x6280c296959af0d2UL, 0x7db799e471565753UL, 0x775aaf35d2edca2cUL,
            0x14b0998ca513f3a9UL, 0x1e5daf5d06a86ed6UL, 0x016af42fe264c957UL, 0x0b87c2fe41df5428UL,
            0x3f0442ca2bfd8655UL, 0x35e9741b88461b2aUL, 0x2ade2f696c8abcabUL, 0x203319b8cf3121d4UL,
            0xed0a421b8376cfa1UL, 0xe7e774ca20cd52deUL, 0xf8d02fb8c401f55fUL, 0xf23d196967ba6820UL,
            0xc6be995d0d98ba5dUL, 0xcc53af8cae232722UL, 0xd364f4fe4aef80a3UL, 0xd989c22fe9541ddcUL,
            0xba63f4969eaa2459UL, 0xb08ec2473d11b926UL, 0xafb99935d9dd1ea7UL, 0xa554afe47a6683d8UL,
            0x91d72fd0104451a5UL, 0x9b3a1901b3ffccdaUL, 0x840d427357336b5bUL, 0x8ee074a2f488f624UL,
            0x2aa6d366972b24daUL, 0x204be5b73490b9a5UL, 0x3f7cbec5d05c1e24UL, 0x3591881473e7835bUL,
            0x0112082019c55126UL, 0x0bff3ef1ba7ecc59UL, 0x14c865835eb26bd8UL, 0x1e255352fd09f6a7UL,
            0x7dcf65eb8af7cf22UL, 0x7722533a294c525dUL, 0x68150848cd80f5dcUL, 0x62f83e996e3b68a3UL,
            0x567bbead0419badeUL, 0x5c96887ca7a227a1UL, 0x43a1d30e436e8020UL, 0x494ce5dfe0d51d5fUL,
            0x8475be7cac92f32aUL, 0x8e9888ad0f296e55UL, 0x91afd3dfebe5c9d4UL, 0x9b42e50e485e54abUL,
            0xafc1653a227c86d6UL, 0xa52c53eb81c71ba9UL, 0xba1b0899650bbc28UL, 0xb0f63e48c6b02157UL,
            0xd31c08f1b14e18d2UL, 0xd9f13e2012f585adUL, 0xc6c66552f639222cUL, 0xcc2b53835582bf53UL,
            0xf8a8d3b73fa06d2eUL, 0xf245e5669c1bf051UL, 0xed72be1478d757d0UL, 0xe79f88c5db6ccaafUL,

            0x0000000000000000UL, 0xb0bc2e589204f500UL, 0x55a17ae27c9e796bUL, 0xe51d54baee9a8c6bUL,
            0xab42f5c4f93cf2d6UL, 0x1bfedb9c6b3807d6UL, 0xfee38f2685a28bbdUL, 0x4e5fa17e17a67ebdUL,
            0x625ccddaaaee76c7UL, 0xd2e0e38238ea83c7UL, 0x37fdb738d6700facUL, 0x874199604474faacUL,
            0xc91e381e53d28411UL, 0x79a21646c1d67111UL, 0x9cbf42fc2f4cfd7aUL, 0x2c036ca4bd48087aUL,
            0xc4b99bb555dced8eUL, 0x7405b5edc7d8188eUL, 0x9118e157294294e5UL, 0x21a4cf0fbb4661e5UL,
            0x6ffb6e71ace01f58UL, 0xdf4740293ee4ea58UL, 0x3a5a1493d07e6633UL, 0x8ae63acb427a9333UL,
            0xa6e5566fff329b49UL, 0x165978376d366e49UL, 0xf3442c8d83ace222UL, 0x43f802d511a81722UL,
            0x0da7a3ab060e699fUL, 0xbd1b8df3940a9c9fUL, 0x5806d9497a9010f4UL, 0xe8baf711e894e5f4UL,
            0xbdaa1139f32e4877UL, 0x0d163f61612abd77UL, 0xe80b6bdb8fb0311cUL, 0x58b745831db4c41cUL,
            0x16e8e4fd0a12baa1UL, 0xa654caa598164fa1UL, 0x43499e1f768cc3caUL, 0xf3f5b047e48836caUL,
            0xdff6dce359c03eb0UL, 0x6f4af2bbcbc4cbb0UL, 0x8a57a601255e47dbUL, 0x3aeb8859b75ab2dbUL,
            0x74b42927a0fccc66UL, 0xc408077f32f83966UL, 0x211553c5dc62b50dUL, 0x91a97d9d4e66400dUL,
            0x79138a8ca6f2a5f9UL, 0xc9afa4d434f650f9UL, 0x2cb2f06eda6cdc92UL, 0x9c0ede3648682992UL,
            0xd2517f485fce572fUL, 0x62ed5110cdcaa22fUL, 0x87f005aa23502e44UL, 0x374c2bf2b154db44UL,
            0x1b4f47560c1cd33eUL, 0xabf3690e9e18263eUL, 0x4eee3db47082aa55UL, 0xfe5213ece2865f55UL,
            0xb00db292f52021e8UL, 0x00b19cca6724d4e8UL, 0xe5acc87089be5883UL, 0x5510e6281bbaad83UL,
            0x4f8d0420becb0385UL, 0xff312a782ccff685UL, 0x1a2c7ec2c2557aeeUL, 0xaa90509a50518feeUL,
            0xe4cff1e447f7f153UL, 0x5473dfbcd5f30453UL, 0xb16e8b063b698838UL, 0x01d2a55ea96d7d38UL,
            0x2dd1c9fa14257542UL, 0x9d6de7a286218042UL, 0x7870b31868bb0c29UL, 0xc8cc9d40fabff929UL,
            0x86933c3eed198794UL, 0x362f12667f1d7294UL, 0xd33246dc9187feffUL, 0x638e688403830bffUL,
            0x8b349f95eb17ee0bUL, 0x3b88b1cd79131b0bUL, 0xde95e57797899760UL, 0x6e29cb2f058d6260UL,
            0x20766a51122b1cddUL, 0x90ca4409802fe9ddUL, 0x75d710b36eb565b6UL, 0xc56b3eebfcb190b6UL,
            0xe968524f41f998ccUL, 0x59d47c17d3fd6dccUL, 0xbcc928ad3d67e1a7UL, 0x0c7506f5af6314a7UL,
            0x422aa78bb8c56a1aUL, 0xf29689d32ac19f1aUL, 0x178bdd69c45b1371UL, 0xa737f331565fe671UL,
            0xf22715194de54bf2UL, 0x429b3b41dfe1bef2UL, 0xa7866ffb317b3299UL, 0x173a41a3a37fc799UL,
            0x5965e0ddb4d9b924UL, 0xe9d9ce8526dd4c24UL, 0x0cc49a3fc847c04fUL, 0xbc78b4675a43354fUL,
            0x907bd8c3e70b3d35UL, 0x20c7f69b750fc835UL, 0xc5daa2219b95445eUL, 0x75668c790991b15eUL,
            0x3b392d071e37cfe3UL, 0x8b85035f8c333ae3UL, 0x6e9857e562a9b688UL, 0xde2479bdf0ad4388UL,
            0x369e8eac1839a67cUL, 0x8622a0f48a3d537cUL, 0x633ff44e64a7df17UL, 0xd383da16f6a32a17UL,
            0x9ddc7b68e10554aaUL, 0x2d6055307301a1aaUL, 0xc87d018a9d9b2dc1UL, 0x78c12fd20f9fd8c1UL,
            0x54c24376b2d7d0bbUL, 0xe47e6d2e20d325bbUL, 0x01633994ce49a9d0UL, 0xb1df17cc5c4d5cd0UL,
            0xff80b6b24beb226dUL, 0x4f3c98ead9efd76dUL, 0xaa21cc5037755b06UL, 0x1a9de208a571ae06UL,
            0x9f1a08417d96070aUL, 0x2fa62619ef92f20aUL, 0xcabb72a301087e61UL, 0x7a075cfb930c8b61UL,
            0x3458fd8584aaf5dcUL, 0x84e4d3dd16ae00dcUL, 0x61f98767f8348cb7UL, 0xd145a93f6a3079b7UL,
            0xfd46c59bd77871cdUL, 0x4dfaebc3457c84cdUL, 0xa8e7bf79abe608a6UL, 0x185b912139e2fda6UL,
            0x5604305f2e44831bUL, 0xe6b81e07bc40761bUL, 0x03a54abd52dafa70UL, 0xb31964e5c0de0f70UL,
            0x5ba393f4284aea84UL, 0xeb1fbdacba4e1f84UL, 0x0e02e91654d493efUL, 0xbebec74ec6d066efUL,
            0xf0e16630d1761852UL, 0x405d48684372ed52UL, 0xa5401cd2ade86139UL, 0x15fc328a3fec9439UL,
            0x39ff5e2e82a49c43UL, 0x8943707610a06943UL, 0x6c5e24ccfe3ae528UL, 0xdce20a946c3e1028UL,
            0x92bdabea7b986e95UL, 0x220185b2e99c9b95UL, 0xc71cd108070617feUL, 0x77a0ff509502e2feUL,
            0x22b019788eb84f7dUL, 0x920c37201cbcba7dUL, 0x7711639af2263616UL, 0xc7ad4dc26022c316UL,
            0x89f2ecbc7784bdabUL, 0x394ec2e4e58048abUL, 0xdc53965e0b1ac4c0UL, 0x6cefb806991e31c0UL,
            0x40ecd4a2245639baUL, 0xf050fafab652ccbaUL, 0x154dae4058c840d1UL, 0xa5f18018caccb5d1UL,
            0xebae2166dd6acb6cUL, 0x5b120f3e4f6e3e6cUL, 0xbe0f5b84a1f4b207UL, 0x0eb375dc33f04707UL,
            0xe60982cddb64a2f3UL, 0x56b5ac95496057f3UL, 0xb3a8f82fa7fadb98UL, 0x0314d67735fe2e98UL,
            0x4d4b770922585025UL, 0xfdf75951b05ca525UL, 0x18ea0deb5ec6294eUL, 0xa85623b3ccc2dc4eUL,
            0x84554f17718ad434UL, 0x34e9614fe38e2134UL, 0xd1f435f50d14ad5fUL, 0x61481bad9f10585fUL,
            0x2f17bad388b626e2UL, 0x9fab948b1ab2d3e2UL, 0x7ab6c031f4285f89UL, 0xca0aee69662caa89UL,
            0xd0970c61c35d048fUL, 0x602b22395159f18fUL, 0x85367683bfc37de4UL, 0x358a58db2dc788e4UL,
            0x7bd5f9a53a61f659UL, 0xcb69d7fda8650359UL, 0x2e74834746ff8f32UL, 0x9ec8ad1fd4fb7a32UL,
            0xb2cbc1bb69b37248UL, 0x0277efe3fbb78748UL, 0xe76abb59152d0b23UL, 0x57d695018729fe23UL,
            0x1989347f908f809eUL, 0xa9351a27028b759eUL, 0x4c284e9dec11f9f5UL, 0xfc9460c57e150cf5UL,
            0x142e97d49681e901UL, 0xa492b98c04851c01UL, 0x418fed36ea1f906aUL, 0xf133c36e781b656aUL,
            0xbf6c62106fbd1bd7UL, 0x0fd04c48fdb9eed7UL, 0xeacd18f2132362bcUL, 0x5a7136aa812797bcUL,
            0x76725a0e3c6f9fc6UL, 0xc6ce7456ae6b6ac6UL, 0x23d320ec40f1e6adUL, 0x936f0eb4d2f513adUL,
            0xdd30afcac5536d10UL, 0x6d8c819257579810UL, 0x8891d528b9cd147bUL, 0x382dfb702bc9e17bUL,
            0x6d3d1d5830734cf8UL, 0xdd813300a277b9f8UL, 0x389c67ba4ced3593UL, 0x882049e2dee9c093UL,
            0xc67fe89cc94fbe2eUL, 0x76c3c6c45b4b4b2eUL, 0x93de927eb5d1c745UL, 0x2362bc2627d53245UL,
            0x0f61d0829a9d3a3fUL, 0xbfddfeda0899cf3fUL, 0x5ac0aa60e6034354UL, 0xea7c84387407b654UL,
            0xa423254663a1c8e9UL, 0x149f0b1ef1a53de9UL, 0xf1825fa41f3fb182UL, 0x413e71fc8d3b4482UL,
            0xa98486ed65afa176UL, 0x1938a8b5f7ab5476UL, 0xfc25fc0f1931d81dUL, 0x4c99d2578b352d1dUL,
            0x02c673299c9353a0UL, 0xb27a5d710e97a6a0UL, 0x576709cbe00d2acbUL, 0xe7db27937209dfcbUL,
            0xcbd84b37cf41d7b1UL, 0x7b64656f5d4522b1UL, 0x9e7931d5b3dfaedaUL, 0x2ec51f8d21db5bdaUL,
            0x609abef3367d2567UL, 0xd02690aba479d067UL, 0x353bc4114ae35c0cUL, 0x8587ea49d8e7a90cUL,
        };

        private static UInt64[] m_uX2N =
        {
            0x0080000000000000UL, 0x0000800000000000UL, 0x0000000080000000UL, 0x9a6c9329ac4bc9b5UL,
            0x10f4bb0f129310d6UL, 0x70f05dcea2ebd226UL, 0x311211205672822dUL, 0x2fc297db0f46c96eUL,
            0xca4d536fabf7da84UL, 0xfb4cdc3b379ee6edUL, 0xea261148df25140aUL, 0x59ccb2c07aa6c9b4UL,
            0x20b3674a839af27aUL, 0x2d8e1986da94d583UL, 0x42cdf4c20337635dUL, 0x1d78724bf0f26839UL,
            0xb96c84e0afb34bd5UL, 0x5d2e1fcd2df0a3eaUL, 0xcd9506572332be42UL, 0x23bda2427f7d690fUL,
            0x347a953232374f07UL, 0x1c2a807ac2a8ceeaUL, 0x9b92ad0e14fe1460UL, 0x2574114889f670b2UL,
            0x4a84a6c45e3bf520UL, 0x915bbac21cd1c7ffUL, 0xb0290ec579f291f5UL, 0xcf2548505c624e6eUL,
            0xb154f27bf08a8207UL, 0xce4e92344baf7d35UL, 0x51da8d7e057c5eb3UL, 0x9fb10823f5be15dfUL,
            0x73b825b3ff1f71cfUL, 0x5db436c5406ebb74UL, 0xfa7ed8f3ec3f2bcaUL, 0xc4d58efdc61b9ef6UL,
            0xa7e39e61e855bd45UL, 0x97ad46f9dd1bf2f1UL, 0x1a0abb01f853ee6bUL, 0x3f0827c3348f8215UL,
            0x4eb68c4506134607UL, 0x4a46f6de5df34e0aUL, 0x2d855d6a1c57a8ddUL, 0x8688da58e1115812UL,
            0x5232f417fc7c7300UL, 0xa4080fb2e767d8daUL, 0xd515a7e17693e562UL, 0x1181f7c862e94226UL,
            0x9e23cd058204ca91UL, 0x9b8992c57a0aed82UL, 0xb2c0afb84609b6ffUL, 0x2f7160553a5ea018UL,
            0x3cd378b5c99f2722UL, 0x814054ad61a3b058UL, 0xbf766189fce806d8UL, 0x85a5e898ac49f86fUL,
            0x34830d11bc84f346UL, 0x9644d95b173c8c1cUL, 0x150401ac9ac759b1UL, 0xebe1f7f46fb00ebaUL,
            0x8ee4ce0c2e2bd662UL, 0x4000000000000000UL, 0x2000000000000000UL, 0x0800000000000000UL,
        };

        //public static UInt64 ComputeSlicedSpan(
        //    ReadOnlySpan<byte> pSrc,
        //    UInt64 uCrc
        //)
        //{
        //    var u1 = new ReadOnlySpan<ulong>(CRC64.m_u1);
        //    var u32 = new ReadOnlySpan<ulong>(CRC64.m_u32);
        //    var pSrcLongs = MemoryMarshal.Cast<byte, ulong>(pSrc);

        //    {
        //        //byte* pData = pSrc;
        //        int offset = 0;
        //        ulong uSize = (ulong)pSrc.Length;

        //        int uBytes;
        //        ulong uStop;

        //        uCrc ^= ~0UL;

        //        uStop = uSize - (uSize % 32);
        //        if (uStop >= 2 * 32)
        //        {
        //            ulong uCrc0 = 0;
        //            ulong uCrc1 = 0;
        //            ulong uCrc2 = 0;
        //            ulong uCrc3 = 0;

        //            int lastOffset = (offset + (int)uStop - 32) / 8;
        //            uSize -= uStop;
        //            uCrc0 = uCrc;

        //            for (; offset < lastOffset; offset += 4)
        //            {
        //                UInt64 b0;
        //                UInt64 b1;
        //                UInt64 b2;
        //                UInt64 b3;

        //                b0 = pSrcLongs[offset + 0] ^ uCrc0;
        //                b1 = pSrcLongs[offset + 1] ^ uCrc1;
        //                b2 = pSrcLongs[offset + 2] ^ uCrc2;
        //                b3 = pSrcLongs[offset + 3] ^ uCrc3;

        //                uCrc0 = u32[(int)((7) * 256 + ((b0) & (256 - 1)))];
        //                b0 >>= 8;
        //                uCrc1 = u32[(int)((7) * 256 + ((b1) & (256 - 1)))];
        //                b1 >>= 8;
        //                uCrc2 = u32[(int)((7) * 256 + ((b2) & (256 - 1)))];
        //                b2 >>= 8;
        //                uCrc3 = u32[(int)((7) * 256 + ((b3) & (256 - 1)))];
        //                b3 >>= 8;
        //                uCrc0 ^= u32[(int)((6) * 256 + ((b0) & (256 - 1)))];
        //                b0 >>= 8;
        //                uCrc1 ^= u32[(int)((6) * 256 + ((b1) & (256 - 1)))];
        //                b1 >>= 8;
        //                uCrc2 ^= u32[(int)((6) * 256 + ((b2) & (256 - 1)))];
        //                b2 >>= 8;
        //                uCrc3 ^= u32[(int)((6) * 256 + ((b3) & (256 - 1)))];
        //                b3 >>= 8;
        //                uCrc0 ^= u32[(int)((5) * 256 + ((b0) & (256 - 1)))];
        //                b0 >>= 8;
        //                uCrc1 ^= u32[(int)((5) * 256 + ((b1) & (256 - 1)))];
        //                b1 >>= 8;
        //                uCrc2 ^= u32[(int)((5) * 256 + ((b2) & (256 - 1)))];
        //                b2 >>= 8;
        //                uCrc3 ^= u32[(int)((5) * 256 + ((b3) & (256 - 1)))];
        //                b3 >>= 8;
        //                uCrc0 ^= u32[(int)((4) * 256 + ((b0) & (256 - 1)))];
        //                b0 >>= 8;
        //                uCrc1 ^= u32[(int)((4) * 256 + ((b1) & (256 - 1)))];
        //                b1 >>= 8;
        //                uCrc2 ^= u32[(int)((4) * 256 + ((b2) & (256 - 1)))];
        //                b2 >>= 8;
        //                uCrc3 ^= u32[(int)((4) * 256 + ((b3) & (256 - 1)))];
        //                b3 >>= 8;
        //                uCrc0 ^= u32[(int)((3) * 256 + ((b0) & (256 - 1)))];
        //                b0 >>= 8;
        //                uCrc1 ^= u32[(int)((3) * 256 + ((b1) & (256 - 1)))];
        //                b1 >>= 8;
        //                uCrc2 ^= u32[(int)((3) * 256 + ((b2) & (256 - 1)))];
        //                b2 >>= 8;
        //                uCrc3 ^= u32[(int)((3) * 256 + ((b3) & (256 - 1)))];
        //                b3 >>= 8;
        //                uCrc0 ^= u32[(int)((2) * 256 + ((b0) & (256 - 1)))];
        //                b0 >>= 8;
        //                uCrc1 ^= u32[(int)((2) * 256 + ((b1) & (256 - 1)))];
        //                b1 >>= 8;
        //                uCrc2 ^= u32[(int)((2) * 256 + ((b2) & (256 - 1)))];
        //                b2 >>= 8;
        //                uCrc3 ^= u32[(int)((2) * 256 + ((b3) & (256 - 1)))];
        //                b3 >>= 8;
        //                uCrc0 ^= u32[(int)((1) * 256 + ((b0) & (256 - 1)))];
        //                b0 >>= 8;
        //                uCrc1 ^= u32[(int)((1) * 256 + ((b1) & (256 - 1)))];
        //                b1 >>= 8;
        //                uCrc2 ^= u32[(int)((1) * 256 + ((b2) & (256 - 1)))];
        //                b2 >>= 8;
        //                uCrc3 ^= u32[(int)((1) * 256 + ((b3) & (256 - 1)))];
        //                b3 >>= 8;
        //                uCrc0 ^= u32[(int)((0) * 256 + ((b0) & (256 - 1)))];
        //                uCrc1 ^= u32[(int)((0) * 256 + ((b1) & (256 - 1)))];
        //                uCrc2 ^= u32[(int)((0) * 256 + ((b2) & (256 - 1)))];
        //                uCrc3 ^= u32[(int)((0) * 256 + ((b3) & (256 - 1)))];
        //            }

        //            uCrc = 0;
        //            uCrc ^= pSrcLongs[offset + 0] ^ uCrc0;
        //            uCrc = (uCrc >> 8) ^ u1[(int)(((uCrc) & (256 - 1)))];
        //            uCrc = (uCrc >> 8) ^ u1[(int)(((uCrc) & (256 - 1)))];
        //            uCrc = (uCrc >> 8) ^ u1[(int)(((uCrc) & (256 - 1)))];
        //            uCrc = (uCrc >> 8) ^ u1[(int)(((uCrc) & (256 - 1)))];
        //            uCrc = (uCrc >> 8) ^ u1[(int)(((uCrc) & (256 - 1)))];
        //            uCrc = (uCrc >> 8) ^ u1[(int)(((uCrc) & (256 - 1)))];
        //            uCrc = (uCrc >> 8) ^ u1[(int)(((uCrc) & (256 - 1)))];
        //            uCrc = (uCrc >> 8) ^ u1[(int)(((uCrc) & (256 - 1)))];
        //            uCrc ^= pSrcLongs[offset + 1] ^ uCrc1;
        //            uCrc = (uCrc >> 8) ^ u1[(int)(((uCrc) & (256 - 1)))];
        //            uCrc = (uCrc >> 8) ^ u1[(int)(((uCrc) & (256 - 1)))];
        //            uCrc = (uCrc >> 8) ^ u1[(int)(((uCrc) & (256 - 1)))];
        //            uCrc = (uCrc >> 8) ^ u1[(int)(((uCrc) & (256 - 1)))];
        //            uCrc = (uCrc >> 8) ^ u1[(int)(((uCrc) & (256 - 1)))];
        //            uCrc = (uCrc >> 8) ^ u1[(int)(((uCrc) & (256 - 1)))];
        //            uCrc = (uCrc >> 8) ^ u1[(int)(((uCrc) & (256 - 1)))];
        //            uCrc = (uCrc >> 8) ^ u1[(int)(((uCrc) & (256 - 1)))];
        //            uCrc ^= pSrcLongs[offset + 2] ^ uCrc2;
        //            uCrc = (uCrc >> 8) ^ u1[(int)(((uCrc) & (256 - 1)))];
        //            uCrc = (uCrc >> 8) ^ u1[(int)(((uCrc) & (256 - 1)))];
        //            uCrc = (uCrc >> 8) ^ u1[(int)(((uCrc) & (256 - 1)))];
        //            uCrc = (uCrc >> 8) ^ u1[(int)(((uCrc) & (256 - 1)))];
        //            uCrc = (uCrc >> 8) ^ u1[(int)(((uCrc) & (256 - 1)))];
        //            uCrc = (uCrc >> 8) ^ u1[(int)(((uCrc) & (256 - 1)))];
        //            uCrc = (uCrc >> 8) ^ u1[(int)(((uCrc) & (256 - 1)))];
        //            uCrc = (uCrc >> 8) ^ u1[(int)(((uCrc) & (256 - 1)))];
        //            uCrc ^= pSrcLongs[offset + 3] ^ uCrc3;
        //            uCrc = (uCrc >> 8) ^ u1[(int)(((uCrc) & (256 - 1)))];
        //            uCrc = (uCrc >> 8) ^ u1[(int)(((uCrc) & (256 - 1)))];
        //            uCrc = (uCrc >> 8) ^ u1[(int)(((uCrc) & (256 - 1)))];
        //            uCrc = (uCrc >> 8) ^ u1[(int)(((uCrc) & (256 - 1)))];
        //            uCrc = (uCrc >> 8) ^ u1[(int)(((uCrc) & (256 - 1)))];
        //            uCrc = (uCrc >> 8) ^ u1[(int)(((uCrc) & (256 - 1)))];
        //            uCrc = (uCrc >> 8) ^ u1[(int)(((uCrc) & (256 - 1)))];
        //            uCrc = (uCrc >> 8) ^ u1[(int)(((uCrc) & (256 - 1)))];
        //            offset += 4;
        //        }

        //        for (uBytes = 0; uBytes < (int)uSize; ++uBytes)
        //            uCrc = (uCrc >> 8) ^ u1[(int)(uCrc ^ pSrc[offset + uBytes]) & (256 - 1)];

        //        return (uCrc ^ ~0UL);
        //    }
        //}

        /// <summary>
        /// Compute the CRC64 of the input data using the Azure Storage CRC64 polynomial.
        /// </summary>
        /// <param name="src">The source data on which to compute the CRC64.</param>
        /// <param name="uCrc"></param>
        /// <returns></returns>
        public static UInt64 ComputeSlicedSafe(ReadOnlySpan<byte> src, ulong uCrc)
        {
            int pData = 0;
            ulong uSize = (ulong)src.Length;

            ulong uBytes, uStop;

            uCrc ^= ~0UL;

            // No need to do alignment for .NET. If we accept an offset
            // in this method, it can re-enabled

            //uStop = ((ulong)(-(long)pData)) & (sizeof(UInt64) - 1);
            //if (uStop != 0)
            //{
            //    if (uStop > uSize)
            //        uStop = uSize;
            //    for (uBytes = 0; uBytes < uStop; ++uBytes)
            //        uCrc = (uCrc >> 8) ^ m_u1[((uCrc ^ pData[uBytes]) & (256 - 1))];
            //    uSize -= uStop;
            //    pData += uStop;
            //}

            uBytes = 0;
            uStop = uSize - (uSize % 32);
            if (uStop >= 2 * 32)
            {
                UInt64 uCrc0 = 0;
                UInt64 uCrc1 = 0;
                UInt64 uCrc2 = 0;
                UInt64 uCrc3 = 0;
                int pLast = pData + (int)uStop - 32;
                uSize -= uStop;
                uCrc0 = uCrc;

                for (; pData < pLast; pData += 32)
                {
                    UInt64 b0;
                    UInt64 b1;
                    UInt64 b2;
                    UInt64 b3;

                    b0 = BinaryPrimitives.ReadUInt64LittleEndian(src.Slice(pData + (0) + 8 * (0))) ^ uCrc0;
                    b1 = BinaryPrimitives.ReadUInt64LittleEndian(src.Slice(pData + (0) + 8 * (1))) ^ uCrc1;
                    b2 = BinaryPrimitives.ReadUInt64LittleEndian(src.Slice(pData + (0) + 8 * (2))) ^ uCrc2;
                    b3 = BinaryPrimitives.ReadUInt64LittleEndian(src.Slice(pData + (0) + 8 * (3))) ^ uCrc3;
                    uCrc0 = m_u32[(7) * 256 + ((b0) & (256 - 1))];
                    b0 >>= 8;
                    uCrc1 = m_u32[(7) * 256 + ((b1) & (256 - 1))];
                    b1 >>= 8;
                    uCrc2 = m_u32[(7) * 256 + ((b2) & (256 - 1))];
                    b2 >>= 8;
                    uCrc3 = m_u32[(7) * 256 + ((b3) & (256 - 1))];
                    b3 >>= 8;
                    uCrc0 ^= m_u32[(6) * 256 + ((b0) & (256 - 1))];
                    b0 >>= 8;
                    uCrc1 ^= m_u32[(6) * 256 + ((b1) & (256 - 1))];
                    b1 >>= 8;
                    uCrc2 ^= m_u32[(6) * 256 + ((b2) & (256 - 1))];
                    b2 >>= 8;
                    uCrc3 ^= m_u32[(6) * 256 + ((b3) & (256 - 1))];
                    b3 >>= 8;
                    uCrc0 ^= m_u32[(5) * 256 + ((b0) & (256 - 1))];
                    b0 >>= 8;
                    uCrc1 ^= m_u32[(5) * 256 + ((b1) & (256 - 1))];
                    b1 >>= 8;
                    uCrc2 ^= m_u32[(5) * 256 + ((b2) & (256 - 1))];
                    b2 >>= 8;
                    uCrc3 ^= m_u32[(5) * 256 + ((b3) & (256 - 1))];
                    b3 >>= 8;
                    uCrc0 ^= m_u32[(4) * 256 + ((b0) & (256 - 1))];
                    b0 >>= 8;
                    uCrc1 ^= m_u32[(4) * 256 + ((b1) & (256 - 1))];
                    b1 >>= 8;
                    uCrc2 ^= m_u32[(4) * 256 + ((b2) & (256 - 1))];
                    b2 >>= 8;
                    uCrc3 ^= m_u32[(4) * 256 + ((b3) & (256 - 1))];
                    b3 >>= 8;
                    uCrc0 ^= m_u32[(3) * 256 + ((b0) & (256 - 1))];
                    b0 >>= 8;
                    uCrc1 ^= m_u32[(3) * 256 + ((b1) & (256 - 1))];
                    b1 >>= 8;
                    uCrc2 ^= m_u32[(3) * 256 + ((b2) & (256 - 1))];
                    b2 >>= 8;
                    uCrc3 ^= m_u32[(3) * 256 + ((b3) & (256 - 1))];
                    b3 >>= 8;
                    uCrc0 ^= m_u32[(2) * 256 + ((b0) & (256 - 1))];
                    b0 >>= 8;
                    uCrc1 ^= m_u32[(2) * 256 + ((b1) & (256 - 1))];
                    b1 >>= 8;
                    uCrc2 ^= m_u32[(2) * 256 + ((b2) & (256 - 1))];
                    b2 >>= 8;
                    uCrc3 ^= m_u32[(2) * 256 + ((b3) & (256 - 1))];
                    b3 >>= 8;
                    uCrc0 ^= m_u32[(1) * 256 + ((b0) & (256 - 1))];
                    b0 >>= 8;
                    uCrc1 ^= m_u32[(1) * 256 + ((b1) & (256 - 1))];
                    b1 >>= 8;
                    uCrc2 ^= m_u32[(1) * 256 + ((b2) & (256 - 1))];
                    b2 >>= 8;
                    uCrc3 ^= m_u32[(1) * 256 + ((b3) & (256 - 1))];
                    b3 >>= 8;
                    uCrc0 ^= m_u32[(0) * 256 + ((b0) & (256 - 1))];
                    uCrc1 ^= m_u32[(0) * 256 + ((b1) & (256 - 1))];
                    uCrc2 ^= m_u32[(0) * 256 + ((b2) & (256 - 1))];
                    uCrc3 ^= m_u32[(0) * 256 + ((b3) & (256 - 1))];
                }

                uCrc = 0;
                uCrc ^= BinaryPrimitives.ReadUInt64LittleEndian(src.Slice(pData + 8 * (0))) ^ uCrc0;
                uCrc = (uCrc >> 8) ^ m_u1[((uCrc) & (256 - 1))];
                uCrc = (uCrc >> 8) ^ m_u1[((uCrc) & (256 - 1))];
                uCrc = (uCrc >> 8) ^ m_u1[((uCrc) & (256 - 1))];
                uCrc = (uCrc >> 8) ^ m_u1[((uCrc) & (256 - 1))];
                uCrc = (uCrc >> 8) ^ m_u1[((uCrc) & (256 - 1))];
                uCrc = (uCrc >> 8) ^ m_u1[((uCrc) & (256 - 1))];
                uCrc = (uCrc >> 8) ^ m_u1[((uCrc) & (256 - 1))];
                uCrc = (uCrc >> 8) ^ m_u1[((uCrc) & (256 - 1))];
                uCrc ^= BinaryPrimitives.ReadUInt64LittleEndian(src.Slice(pData + 8 * (1))) ^ uCrc1;
                uCrc = (uCrc >> 8) ^ m_u1[((uCrc) & (256 - 1))];
                uCrc = (uCrc >> 8) ^ m_u1[((uCrc) & (256 - 1))];
                uCrc = (uCrc >> 8) ^ m_u1[((uCrc) & (256 - 1))];
                uCrc = (uCrc >> 8) ^ m_u1[((uCrc) & (256 - 1))];
                uCrc = (uCrc >> 8) ^ m_u1[((uCrc) & (256 - 1))];
                uCrc = (uCrc >> 8) ^ m_u1[((uCrc) & (256 - 1))];
                uCrc = (uCrc >> 8) ^ m_u1[((uCrc) & (256 - 1))];
                uCrc = (uCrc >> 8) ^ m_u1[((uCrc) & (256 - 1))];
                uCrc ^= BinaryPrimitives.ReadUInt64LittleEndian(src.Slice(pData + 8 * (2))) ^ uCrc2;
                uCrc = (uCrc >> 8) ^ m_u1[((uCrc) & (256 - 1))];
                uCrc = (uCrc >> 8) ^ m_u1[((uCrc) & (256 - 1))];
                uCrc = (uCrc >> 8) ^ m_u1[((uCrc) & (256 - 1))];
                uCrc = (uCrc >> 8) ^ m_u1[((uCrc) & (256 - 1))];
                uCrc = (uCrc >> 8) ^ m_u1[((uCrc) & (256 - 1))];
                uCrc = (uCrc >> 8) ^ m_u1[((uCrc) & (256 - 1))];
                uCrc = (uCrc >> 8) ^ m_u1[((uCrc) & (256 - 1))];
                uCrc = (uCrc >> 8) ^ m_u1[((uCrc) & (256 - 1))];
                uCrc ^= BinaryPrimitives.ReadUInt64LittleEndian(src.Slice(pData + 8 * (3))) ^ uCrc3;
                uCrc = (uCrc >> 8) ^ m_u1[((uCrc) & (256 - 1))];
                uCrc = (uCrc >> 8) ^ m_u1[((uCrc) & (256 - 1))];
                uCrc = (uCrc >> 8) ^ m_u1[((uCrc) & (256 - 1))];
                uCrc = (uCrc >> 8) ^ m_u1[((uCrc) & (256 - 1))];
                uCrc = (uCrc >> 8) ^ m_u1[((uCrc) & (256 - 1))];
                uCrc = (uCrc >> 8) ^ m_u1[((uCrc) & (256 - 1))];
                uCrc = (uCrc >> 8) ^ m_u1[((uCrc) & (256 - 1))];
                uCrc = (uCrc >> 8) ^ m_u1[((uCrc) & (256 - 1))];
                pData += 32;
            }

            for (uBytes = 0; uBytes < uSize; ++uBytes, ++pData)
            {
                uCrc = (uCrc >> 8) ^ m_u1[((uCrc ^ src[pData]) & (256 - 1))];
            }

            return (uCrc ^ ~0UL);
        }

        #region Concat
        private const UInt64 m_uComplement = ~0UL;
        private const int m_uBitWidth = 64;

        //
        // Given
        //      uFinalCrcA = ComputeCrc (A, uSizeA, uInitialCrcA)
        // and
        //      uFinalCrcB = ComputeCrc (B, uSizeB, uInitialCrcB),
        // compute CRC of concatenation of A and B
        //      uFinalCrcAB = ComputeCrc (AB, uSizeA + uSizeB, uInitialCrcAB)
        // without touching A and B
        //
        // NB: uSizeA and/or uSizeB may be 0s (this trick may be used to "recompute" CRC for another initial value)
        //
        internal static UInt64 Concatenate(
            UInt64 uInitialCrcAB,
            UInt64 uInitialCrcA,
            UInt64 uFinalCrcA,
            UInt64 uSizeA,
            UInt64 uInitialCrcB,
            UInt64 uFinalCrcB,
            UInt64 uSizeB
            )
        {
            var uFinalCrcAB = uFinalCrcA ^ m_uComplement;

            if (uInitialCrcA != uInitialCrcAB)
            {
                uFinalCrcAB ^= MulX_N(uInitialCrcA ^ uInitialCrcAB, uSizeA);
            }

            uFinalCrcAB ^= uInitialCrcB ^ m_uComplement;
            uFinalCrcAB = MulX_N(uFinalCrcAB, uSizeB);
            uFinalCrcAB ^= uFinalCrcB;

            return uFinalCrcAB;
        }

        //
        // Returns MulPoly(a, ComputeX_N(uSize)).
        //
        private static UInt64 MulX_N(
            UInt64 a,
            UInt64 uSize
            )
        {
            var i = 0;

            var r = a;

            for (uSize >>= i; uSize != 0; uSize >>= 1, i += 1)
            {
                if ((uSize & 1) == 1)
                {
                    r = MulPoly(r, m_uX2N[i]);
                }
            }

            return r;
        }

        //
        // Returns (a * b) mod POLY.
        // "a" and "b" are represented in "reversed" order -- LSB is x**(XX-1) coefficient, MSB is x^0 coefficient.
        // "POLY" is represented in the same manner except for omitted x**XX coefficient
        //
        private static UInt64 MulPoly(
            UInt64 a,
            UInt64 b
        )
        {
            return MulPolyUnrolled(a, b);
        }

        //
        // Returns (a * b) mod POLY.
        // "a" and "b" are represented in "reversed" order -- LSB is x**(XX-1) coefficient, MSB is x^0 coefficient.
        // "POLY" is represented in the same manner except for omitted x**XX coefficient
        //
        private static UInt64 MulPolyUnrolled(
            UInt64 a,
            UInt64 b
        )
        {
            // Unrolled version without SSE 4.1.
            var p = poly;
            var p2 = (p >> 1) ^ (p * (p & 1));
            var bw = m_uBitWidth;

            var vt = new UInt64[] { 0, p2, p, p ^ p2 };
            var vs = new[] { bw - 2, bw - 1 };
            var vb = new UInt64[] { (b >> 1) ^ vt[(b & 1) << 1], b };
            var vr = new UInt64[] { 0, 0 };

            for (var i = 0; i < bw; i += 2)
            {
                for (int j = 0; j < 2; ++j)
                {
                    vr[j] ^= vb[j] * ((a >> vs[j]) & 1);
                    vb[j] = (vb[j] >> 2) ^ vt[vb[j] & 3];
                }

                a <<= 2;
            }

            return vr[0] ^ vr[1];
        }
        #endregion
    }
}
